我想在Angular应用中对组件的ngOnInit()方法进行单元测试。 ngOnInit()方法订阅ActivatedRoute data
,并在subscribe方法内部调用一个函数。这是该方法的代码:
component.ts
ngOnInit() {
this.route.data.subscribe(data => this.store.patchState(data));
}
这是我的测试:
component.spec.ts
beforeEach(() => {
fixture = TestBed.createComponent(xyzComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('#ngOnInit should call patchState', async(() => {
const spy = spyOn(store, 'patchState');
// When
component.ngOnInit();
fixture.detectChanges();
// Then
expect(spy.calls.count()).toBe(1, 'patchState has been called once.');
}));
但是,当我运行测试时,出现一个错误,告诉我'从未调用过预期的间谍patchState。'
我相信我的问题来自测试的异步性质,但我不知道为什么它不起作用。
我在这里做错了什么?
谢谢!
将订阅更改为:
this.route.data.subscribe(data => {
console.log('in route subscription);
this.store.patchState(data)
});
如果没有看到console.log('in route subscription')
,则可能是您没有正确嘲笑activatedRoute
。
尝试一下:
describe('xyzComponent', () => {
let store: Store<...>; // for you to fill out
let component: xyzComponent;
let fixture: ComponentFixture<xyzComponent>;
let data$ = new BehaviorSubject({ x: 1 }); // mock data for activatedRoute
beforeEach(async() => {
TestBed.configureTestingModule({
imports: [ StoreModule.forRoot(....) ], // for you to fill out
declarations: [ XYZComponent ],
providers: [
{ provide: ActivatedRoute, useValue: { data: data$ } },
],
}).compileComponents();
});
beforeEach(() => {
store = TestBed.get(store);
spyOn(store, 'patchState').and.callThrough(); // and.callThrough() is optional, do you want it to HAVE both a spy and call the actual implementation?
fixture = TestBed.createComponent(xyzComponent);
component = fixture.componentInstance;
fixture.detectChanges(); // this fixture.detectChanges() will call `ngOnInit` for us, so we don't have to manually call it
});
it('ngOnInit should call patchState', () => {
expect(store.patchState).toHaveBeenCalledWith({ x: 1 });
});
});
希望可以使您畅通无阻。您也可以在以后的测试中更改route.data
,并通过执行data.next$({....})
您的未来值来查看其反应。