如何在函数内触发对事件发射器的订阅。 Angular 单元测试

how to trigger a subscribe to an event emitter inside a function. Angular unit test

我一直在尝试测试一个包含 EventEmitter 订阅的函数,单元测试正在调用订阅,但无法测试订阅中的代码,我的意思是,filtergetDocuments() 即使正在调用订阅,也未经过测试。

  describe('trigger_data test', () => {
    it('not filter in storage', async(() => {
      component.filter = null;
      spyOn(component, 'getDocuments');
      spyOn(mockSharedService.trigger_data, 'subscribe').and.returnValue(of(true));
      component.triggerData();
      expect(mockSharedService.trigger_data.subscribe).toHaveBeenCalled();
      expect(component.filter).toEqual(1); //Error: Expected null to equal 1.
      expect(component.getDocuments).toHaveBeenCalled(); //Error: Expected spy getDocuments to have been called.
    }));
  });

这是函数

  triggerData() {
    this.sharedService.trigger_data.subscribe(() => {
      if (sessionStorage.getItem('filter_pp') !== null) {
        this.filter = Number(sessionStorage.getItem('filter_pp'));
      } else {
        this.filter = 1;
      }
      this.getDocuments();
    });
  }

当另一个组件发出布尔值时,订阅会触发代码。

不是监视 subscribe 方法,而是监视 trigger_data。希望有用。

describe('trigger_data test', () => {
    it('not filter in storage', async(() => {
      component.filter = null;
      spyOn(component, 'getDocuments');
      spyOn(mockSharedService., 'trigger_data').and.returnValue(of(true));
      component.triggerData();
      expect(mockSharedService.trigger_data.subscribe).toHaveBeenCalled();
      expect(component.filter).toEqual(1); //Error: Expected null to equal 1.
      expect(component.getDocuments).toHaveBeenCalled(); //Error: Expected spy getDocuments to have been called.
    }));
  });

您正在监视 subscribe 方法并使其 return 成为一个 Observable,这是不正确的。 (订阅是 Observable 上的一种方法,return 是一个订阅)

您可以通过几种方法解决此问题:

  • 确保 mockSharedService.trigger_data 在创建模拟时设置为正确的 Observable(为此,我认为我们需要查看更多您的测试代码)。
  • 在你的测试中覆盖 mockSharedService.trigger_data 使用:mockSharedService.trigger_data = of(true)(注意:如果 trigger_data 是一个 EventEmitter,TypeScript 不会喜欢这个,你可能需要:mockSharedService.trigger_data = of(true) as any)
  • 如果你想避免转换为 any,就像我在前面的例子中所做的那样,你可以使用:
  const emitter = new EventEmitter();
  mockSharedService.trigger_data = emitter;
  emitter.emit(true);
  • 使 trigger_data 成为一个 return 可观察对象的方法,并使用 spyOn(mockSharedService, 'trigger_data').and.returnValue(of(true)) 监视该方法。但是,这样做还需要您更改 triggerData 实现以调用 trigger_data() 而不是仅作为 属性.
  • 访问它

I've been trying to test a function that contains a subscribe of an EventEmitter

此外,您可能希望使用 Subject 而不是 EventEmitter,EventEmitter 被 Angular 用于其输出绑定。当我们自己实现时,在 Angular 的输出之外,我们可以使用 Subjects 而不是 EventEmitter(为了 Angular 的输出,它实际上扩展了 Subjects。参见:https://github.com/angular/angular/blob/master/packages/core/src/event_emitter.ts#L64