我要测试this.communication.subscribe()
调用,该调用在参数中具有回调:
constructor (private communication: CommunicationProvider)
ngOnInit() {
this.communication.subscribe(() => {
this.router.navigate(["/success"]);
});
}
我已经使用callFake来模拟实现以调用callback()
beforeEach(async(() => {
communicationSpy = jasmine.createSpyObj("CommunicationProvider", ["subscribe"]);
routerSpy = jasmine.createSpyObj<Router>("Router", ["navigate"]);
communicationSpy.subscribe.and.callFake((callback: any) => {
callback();
});
}));
it("should route on callback", (done: DoneFn) => {
setTimeout(() => {
expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
done();
}, 3000);
});
根据代码覆盖率结果,this.router.navigate(["/success"]);
正在覆盖callback()
。
但是"should route on callback"
测试失败了,因为从未调用过routerSpy.navigate
。
为什么?
答案 0 :(得分:0)
因为您永远不会触发订阅。
我不知道您的服务是什么,但是我们将利用您不使用限制运算符(例如take
或takeUntil
)的优势。
首先使用Subject
将您的可观察对象模拟为热流:
component['communication'] = new Subject() as any;
现在,由于每个测试之前都有一个夹具createComponentInstance
,因此您应该在每个测试中都有一个新的组件实例。这意味着您已经调用了ngOnInit
并创建了订阅。
由于流很热,您可以在测试中订阅它:
it('should navigate', done => {
component['communication'].subscribe(() => {
expect(routerSpy.navigate).toHaveBeenCalledWith(["/success"]);
done();
});
(component['communication'] as Subject).next(true);
});
通过next
调用,您可以触发订阅,启动路由器并期望已被调用。
(PS:我已经使用数组语法和Subject
来描述问题,可以随意使用想要触发订阅和模拟依赖项的任何方式)