角分量
public setupObservables() {
this.formFieldChanged$ = this.formField
.valueChanges
.pipe(
debounceTime(100),
distinctUntilChanged((a, b) => a === b),
)
}茉莉花试验
import { of } from 'rxjs';
import { marbles } from 'rxjs-marbles/jasmine';
...
it('should update value on debounced formField change', marbles(m => {
const values = { a: "1", b: "2", c: "3" };
const fakeInputs = m.cold('a 200ms b 50ms c', values);
const expected = m.cold('100ms a 250ms c', values);
// works on stackblitz but otherwise gives TS2540 compiler error
// cannot assign to a read-only property
component.formField.valueChanges = fakeInputs;
component.setupObservables();
m.expect(component.formFieldChanged$).toBeObservable(expected);
}));其目的是使用大理石测试来测试Observable代码的角度反应形式。
valueChanges对象的FormField?发布于 2020-04-25 16:29:28
问题是-你想测试什么。它是单元测试还是e2e测试?如果它是一个单元测试-模拟反应形式,只涵盖你的逻辑,那么你没有问题的valueChanges,因为它是模拟和控制它。
如果这是一个e2e测试-您不应该重新分配valueChanges。任何东西都不应该被模仿/替换,因为它是一个e2e测试。
不过,如果您想要更改valueChanges -使用https://github.com/krzkaczor/ts-essentials#writable
(Writable<typeof component.formField>component.formField).valueChanges = fakeInputs; 它将使属性类型可写。
如果是单元测试,我个人会投票模拟反应性表单,因为在单元测试中,我们只需要测试单元,它的依赖关系应该被模拟/存根。
我们想要模拟的部件的注入
作为一个选项,您可以将表单作为组件的依赖项移动到组件声明中的提供程序。
@Component({
selector: 'app-component',
templateUrl: './app-component.html',
styleUrls: ['./app-component.scss'],
providers: [
{
provide: 'form',
useFactory: () => new FormControl(),
},
],
})
export class AppComponent {
public formFieldChanged$: Observable<unknown>;
constructor(@Inject('form') public readonly formField: FormControl) {
}
public setupObservables(): void {
this.formFieldChanged$ = this.formField
.valueChanges
.pipe(
debounceTime(100),
distinctUntilChanged((a, b) => a === b),
);
}
}然后,您可以简单地在测试中注入一个模拟,而不是它。
it('should update value on debounced formField change', marbles(m => {
const values = { a: "1", b: "2", c: "3" };
const fakeInputs = m.cold('a 200ms b 50ms c', values);
const expected = m.cold('100ms a 250ms c', values);
const formInput = {
valueChanges: fakeInputs,
};
const component = new AppComponent(formInput as any as FormControl);
component.setupObservables();
m.expect(component.formFieldChanged$).toBeObservable(expected);
}));发布于 2021-06-24 09:06:35
使用属性而不是字段是一个更干净的解决方案。
get formFieldChanged$() { return this._formFieldChanged$; }
private _formFieldChanged$: Observable<string>;
...
public setupObservables() {
this._formFieldChanged$ = this.formField
.valueChanges
.pipe(
debounceTime(100),
distinctUntilChanged((a, b) => a === b),
)
}spyOnProperty在这里发挥了魔力,不再需要setupObservables():
it('should update value on debounced formField change', marbles(m => {
const values = { a: "1", b: "2", c: "3" };
const fakeInputs = m.cold('a 200ms b 50ms c', values);
const expected = m.cold('100ms a 250ms c', values);
spyOnProperty(component, 'formFieldChanged$').and.returnValue(fakeInputs);
m.expect(component.formFieldChanged$).toBeObservable(expected);
}));https://stackoverflow.com/questions/61274166
复制相似问题