对FormGroup进行更改后,如何在单元测试中触发valuesChanged可观察到的?

时间:2019-05-14 17:19:58

标签: angular unit-testing angular-reactive-forms

我正在包含响应式表单(FormGroup)和valueChanges订阅的组件上编写单元测试代码,但我还没有弄清楚如何确保valueChanges事件由FormGroup发出。

// In the component under test:
this.formGroup.get('field').valueChanges
     .subscribe((obj: any[]) => {
         debugger; // BREAKPOINT
         dataObject.fieldValues = [ ... ];
         ... details here should be unimportant ...
     });

// In the unit test:
it('should set dataObject from field component', fakeAsync(() => {
        [
    values: string[] = [ ... ];

    component.formGroup.get('field').setValue(values);
    component.formGroup.get('field').updateValueAndValidity({ emitEvent: true });
    fixture.detectChanges();
    tick();

    expect(component.dataObject.fieldValues.length).toEqual(values.length);

}));

我无法获得单元测试规格以达到组件预订代码中的断点。

1 个答案:

答案 0 :(得分:1)

您的tick()fixture.detectChanges()的顺序是关键。

期望,您在设置componentInstance的beforeEarch循环中已经有一个fixture.detectChnages(),那么您需要做的是:

首先调用tick(),因此测试将等待直到设置了该值。之后,您就可以像执行inisde您的期望一样从组件内部访问值。如果随后您希望模板中发生更改,则需要触发fixture.detectChanges,该同步会将您的组件与模板同步。

但重要的是,您在tick()之前叫fixture.detectChanges()

// In the component under test:
this.formGroup.get('field').valueChanges
     .subscribe((obj: any[]) => {
         debugger; // BREAKPOINT
         dataObject.fieldValues = [ ... ];
         ... details here should be unimportant ...
     });

// In the unit test:
it('should set dataObject from field component', fakeAsync(() => {
        [
    values: string[] = [ ... ];

    component.formGroup.get('field').setValue(values);
    component.formGroup.get('field').updateValueAndValidity({ emitEvent: true });

    tick();
    fixture.detectChanges(); // OPTIONAL

    expect(component.dataObject.fieldValues.length).toEqual(values.length);

}));