【问题标题】:How to test multiple sequential calls with Jasmine如何使用 Jasmine 测试多个顺序调用
【发布时间】:2019-01-29 11:42:21
【问题描述】:

我正在尝试测试一个取消订阅所有订阅的函数:

ngOnDestroy() {
        this.tryUnsubscribe(this.carsSubscription);
        this.tryUnsubscribe(this.partsSubscription);
        this.tryUnsubscribe(this.shopsSubscription);
    }

这是我为函数写的测试:

it('should unsubscribe from subscriptions ', () => { 
      spyOn(component, "tryUnsubscribe");     
      component.ngOnDestroy();
      expect(component.tryUnsubscribe).toHaveBeenCalledWith(component['carsSubscription']);
      expect(component.tryUnsubscribe).toHaveBeenCalledWith(component['partsSubscription']);
      expect(component.tryUnsubscribe).toHaveBeenCalledWith(component['shopsSubscription']);
    });

问题:

如果我注释掉一个函数调用,测试仍然通过。

ngOnDestroy() {
        this.tryUnsubscribe(this.carsSubscription);
        //this.tryUnsubscribe(this.partsSubscription);
        this.tryUnsubscribe(this.shopsSubscription);
    }

只有当我注释掉所有这些函数调用时,测试才会失败:

ngOnDestroy() {
        //this.tryUnsubscribe(this.carsSubscription);
        //this.tryUnsubscribe(this.partsSubscription);
        //this.tryUnsubscribe(this.shopsSubscription);
    }

如何正确测试这种功能?我做错了什么?

【问题讨论】:

  • 你能在断言之前注销所有component['...']吗?
  • @Buczkowski 他们都注销 undefined,因为我只是在组件的 TS 代码中创建订阅时才定义这些订阅。
  • 这就是为什么即使你注释掉一些方法执行它也会通过的原因。它将像使用undefined 调用一样被断言。用调用时间检查它怎么样?像 tryUnsubscribe 被调用了 3 次?
  • 好的,你能提供一个代码示例的答案吗?我会投票赞成,如果今天没有人提出更好的解决方案,我会将其标记为正确答案。

标签: angular jasmine rxjs


【解决方案1】:

我会将您的测试重写为以下内容:

it('should unsubscribe from subscriptions ', () => { 
  const spy = spyOn(component, 'tryUnsubscribe');     
  component.ngOnDestroy();

  // Check how many times the spy was called
  expect(spy).toHaveBeenCalledTimes(3);
});

如果您现在取消注释其中一个 tryUnsubscribe 调用,测试应该会失败,因为间谍只被调用了两次。

另一种方法是模拟订阅,或者只是将它们设置为一个虚拟值,以测试 ngDestroy 内部 tryUnsubscribe 是否被这 3 个组件变量调用:

it('test unsubscribing', () => {
  // Mock values
  component.carsSubscription = Observable.of(1).subscribe(() => {});
  component.partsSubscription = Observable.of(1).subscribe(() => {});
  component.shopsSubscription = Observable.of(1).subscribe(() => {});

  const spy = spyOn(component, 'tryUnsubscribe').and.callThrough();     
  component.ngOnDestroy();

  // Check how many times the spy was called
  expect(spy).toHaveBeenCalledTimes(3);

  // Check arguments
  expect(spy.calls.all()[0].args[0]).toEqual(component.carsSubscription);
  expect(spy.calls.all()[1].args[0]).toEqual(component.partsSubscription);
  expect(spy.calls.all()[2].args[0]).toEqual(component.shopsSubscription);
});

Here 是一个有效的测试堆栈闪电战。

【讨论】:

    【解决方案2】:

    也可以使用 Jasmine 调用.allArgs() 方法一次检查所有参数:

    expect(spy.calls.allArgs()).toEqual([
      [component.carsSubscription],
      [component.partsSubscription],
      [component.shopsSubscription]
    ]);
    

    Here 是 Fabian Küng 在 stackblitz 中的修改答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-21
      • 2013-04-19
      • 1970-01-01
      • 2010-12-18
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多