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

Jef*_*y P 5 unit-testing angular angular-reactive-forms

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

// 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);

}));

Run Code Online (Sandbox Code Playgroud)

我无法让单元测试规范命中组件订阅代码中的断点。

Erb*_*nig 8

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

预计您已经fixture.detectChnages()在 beforeEarch 循环内部设置了 componentInstance,那么您需要做的是:

首先调用tick(),因此测试会等待,直到设置该值。之后,您就可以像您期望的那样从组件内部访问该值。如果您希望模板内部发生更改,则需要触发将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);

}));
Run Code Online (Sandbox Code Playgroud)