如何使用Jasmine测试多个顺序调用

时间:2019-01-29 11:42:21

标签: angular jasmine rxjs

我正在尝试测试一个取消所有订阅退订的功能:

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);
    }

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

2 个答案:

答案 0 :(得分: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   是该测试的有效堆叠。

答案 1 :(得分:1)

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

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

Here修改了FabianKüng在stackblitz中的答案。