【问题标题】:Why Jasmine spy function in Angular is not being triggered by callback?为什么 Angular 中的 Jasmine 间谍功能没有被回调触发?
【发布时间】:2018-11-22 13:02:49
【问题描述】:

我想测试在参数中有回调的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 从未被调用过。

为什么?

【问题讨论】:

    标签: angular typescript unit-testing callback jasmine


    【解决方案1】:

    因为您永远不会触发订阅。

    我不知道您的服务是什么,但我们会利用您不使用限制运算符(例如 taketakeUntil)这一事实。

    首先使用 Subject 将您的 observable 模拟为热流:

    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 调用,您触发订阅,启动路由器并期望它被调用。

    (P.S:我已经使用数组语法和Subject 来描述问题,随意使用任何你想要触发订阅和模拟你的依赖项)

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2019-02-05
      • 2022-07-03
      • 2022-10-04
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 2023-03-24
      相关资源
      最近更新 更多