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

gfe*_*els 9 jasmine rxjs angular

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

ngOnDestroy() {
        this.tryUnsubscribe(this.carsSubscription);
        this.tryUnsubscribe(this.partsSubscription);
        this.tryUnsubscribe(this.shopsSubscription);
    }
Run Code Online (Sandbox Code Playgroud)

这是我为该函数编写的测试:

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']);
    });
Run Code Online (Sandbox Code Playgroud)

问题:

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

ngOnDestroy() {
        this.tryUnsubscribe(this.carsSubscription);
        //this.tryUnsubscribe(this.partsSubscription);
        this.tryUnsubscribe(this.shopsSubscription);
    }
Run Code Online (Sandbox Code Playgroud)

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

ngOnDestroy() {
        //this.tryUnsubscribe(this.carsSubscription);
        //this.tryUnsubscribe(this.partsSubscription);
        //this.tryUnsubscribe(this.shopsSubscription);
    }
Run Code Online (Sandbox Code Playgroud)

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

Fab*_*üng 17

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

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

  // Check how many times the spy was called
  expect(spy).toHaveBeenCalledTimes(3);
});
Run Code Online (Sandbox Code Playgroud)

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

另一种方法是模拟订阅,或者只是将它们设置为一个虚拟值来测试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);
});
Run Code Online (Sandbox Code Playgroud)

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


Gen*_*hak 6

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

\n
expect(spy.calls.allArgs()).toEqual([\n  [component.carsSubscription],\n  [component.partsSubscription],\n  [component.shopsSubscription]\n]);\n
Run Code Online (Sandbox Code Playgroud)\n

是修改后的 Fabian K\xc3\xbcng\ 在 stackblitz 中的答案。

\n