首页 > 解决方案 > 如何测试 Angular 中的所有订阅都取消订阅了吗?

问题描述

基本上,我想在调用 ngOnDestroy 后检查是否有任何活动订阅。现在,代码收集组件属性数组中的所有订阅,并在 ngOnDestroy 上取消订阅。我很容易忘记向这个数组添加一个新创建的订阅。想写一个测试来帮助我消除这种情况。

标签: angulartestingrxjs

解决方案


不确定您是否正在尝试测试 ngOnDestroy 方法是否正在结束在您的公共可观察对象上从外部开始的订阅,或者您是否正在尝试查看组件中是否存在任何杂散的内部订阅。

对于前者,您可以编写如下测试:

  it('should end subscriptions when the component is destroyed', () => {
    // Setup the spies
    const spy = jasmine.createSpy();
    const noop = () => {};

    // Start the subscriptions
    const streams = [component.streamOne$, component.streamTwo$, component.streamThree$];
    streams.forEach(stream => stream.subscribe(noop, noop, spy));

    // Destroy the component
    component.ngOnDestroy();

    // Verify the spy was called three times (once for each subscription)
    expect(spy).toHaveBeenCalledTimes(streams.length);
  });

这将确保 ngOnDestroy 完成它应该做的事情并结束在该组件的公共 observables 上启动的任何订阅。

但是,如果您关心的是后者,那么检查杂散订阅的唯一方法是通过猴子修补 rxjs 中的 Observable。这个图书馆做得很好(我不附属)。用它编写测试将是微不足道的:

import { setup, track, printSubscribers } from 'observable-profiler';

describe('MyComponent', () => {
  beforeAll(() => {
    setup(Observable);
  });

  it('should not have any stray subscriptions', () => {
    track();

    const fixture = TestBed.createComponent(MyComponent);
    fixture.detectChanges();
    fixture.destroy()

    const subscriptions = track(false);
    expect(subscriptions).toBeUndefined();
  });
  ...

推荐阅读