您如何在 ngOnInit 生命周期中测试可观察对象?

How do you test observables in the ngOnInit lifecycle?

我看过很多关于测试 observable 的文章,包括 writing marble tests 但不知何故,我仍然找不到关于如何在我的 ngOnInit 周期中测试组件中的简单 observable 的直接答案。

ngOnInit(): void {
    this.selectedMembers$.subscribe((members) => {
        if (!!members) {
            this.store.dispatch(actions.getPCPs());
        }
    });

    this.membersForm.valueChanges.subscribe((id) => {
        if (!!id.member_id) {
            if (id.member_id === 'null') {
                this.store.dispatch(actions.getMembers());

                return;
            }
            this.store.dispatch(
                actions.getSelectedMember({ member_id: id.member_id }),
            );
        }
    });

    this.config$.subscribe((config) => {
        if (!!config) {
            config.mobile_filters.controls.forEach((control) => {
                this.formControlService.addControlToFormGroup(
                    this.mobileFiltersForm,
                    control,
                );
            });
        }
    });
}

有没有一种直接的方法可以监视此组件并检查这些可观察对象是否正在发射某些东西?

 it('should test observables in ngOnInit', fakeAsync(() => {
    spyOn(component.selectedMembers$, 'subscribe')
    let myData;
    component.selectedMembers$.subscribe((data) => {
        myData = data;
        console.log('data',data);
        expect(myData).toEqual(data);
    })
}));

例如这部分:

this.selectedMembers$.subscribe((members) => {
    if (!!members) {
        this.store.dispatch(actions.getPCPs());
    }
});

在你的测试中:

const spy = spyOn(store, 'dispatch');
component.selectedMembers$.next('abc');
expect(spy).toHaveBeenCalledWith('abc');

你是在问这样的问题吗?

你到底想测试什么?

如果您只想在测试完成之前调用订阅回调,您可以在测试中使用 tick() 方法 (https://angular.io/api/core/testing/tick):

it('should dispatch if members are provided / selected', fakeAsync(() => {
  // arrange
  const dispatchSpy = spyOn(component.store, 'dispatch');
  const membersToEmit = ['member-1', 'member-2'];
  component.selectedMembers$ = of(membersToEmit) // of from 'rxjs';

  // act
  component.ngOnInit();
  // alternatively you could call:
  // fixture.detectChanges();

  tick();  // causes your Observable to emit, so that the subscribe callback gets called 

  // assert
  expect(dispatchSpy).toHaveBeenCalled();
}));