繁体   English   中英

如何在 Angular 中测试 form.valueChanges?

[英]How to test form.valueChanges in Angular?

如何正确地进行单元测试(Karma、Jasmine),即valueChangesFormUpdated分派FormUpdated操作?

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [...],
    providers: [
      { provide: Store, useValue: MOCK_STORE },
    ],
    declarations: [FormComponent],
    schemas: [NO_ERRORS_SCHEMA]
  })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(FormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});
export class FormComponent implements OnInit {
    searchForm: FormGroup;

    constructor(private readonly fb: FormBuilder, private readonly store: Store<AppState>) {
    }

    ngOnInit(): void {
        this.searchForm = this.fb.group({});
        this.searchForm.valueChanges.subscribe(value => this.store.dispatch(new FormUpdated(value)));
    }
}

我试过这样的事情:

it('should dispatch action for valueChanges', () => {
    const spy = spyOn(component['store'], 'dispatch');
    spyOn(component.searchForm, 'valueChanges').and.returnValue(of({}));

    expect(spy).toHaveBeenCalledTimes(1);
});

但这不起作用 - 间谍没有被调用。

[Edit1] - 基于评论和回答:

问题在于测试的异步性。 ngOnInit某些部分调用setTimeout(() => this.searchForm.get('field').updateValueAndValidity();) ) 导致对this.searchForm.valueChanges()this.store.dispatch因此实际上调用this.store.dispatch但在expect(spy).toHaveBeenCalledTimes(1)

我尝试添加fakeAsync()tick()flushMicrotasks()但结果相同。

it('should dispatch action for valueChanges', () => {
    const spy = spyOn(component['store'], 'dispatch');
    spyOn(component.searchForm, 'valueChanges').and.returnValue(of({}));

    tick();
    flushMicrotasks();

    expect(spy).toHaveBeenCalledTimes(1);
});

您想在没有输入的表单上测试更改。 也许试试这个:

this.searchForm = this.fb.group({description: ['your_input']});

.

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [...],
    providers: [
      { provide: Store, useValue: MOCK_STORE },
    ],
    declarations: [FormComponent],
    schemas: [NO_ERRORS_SCHEMA]
  })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(FormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});

it('should dispatch action for valueChanges', () => {
    const spy = spyOn(TestBed.get(Store<AppState>), 'dispatch') 
    component.searchForm.controls['your_input'].setValue('test') // This will trigger change
    expect(spy).toHaveBeenCalledTimes(1);
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM