как вызвать подписку на источник событий внутри функции. Angular модульный тест - PullRequest
1 голос
/ 19 апреля 2020

Я пытался протестировать функцию, которая содержит подписку на EventEmitter, модульный тест вызывает подписку, но было невозможно проверить код внутри подписки, я имею в виду filter и getDocuments() не тестируются даже при вызове подписки.

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

Когда другой компонент выдает логическое значение, подписка запускает код.

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Вы шпионите за методом subscribe и заставляете его возвращать Наблюдаемое, что неверно. (метод подписки в Observable, который возвращает подписку)

Существует несколько способов go исправить это:

  • Убедитесь, что для mockSharedService.trigger_data установлено значение Исправить Наблюдаемый при создании макета (для этого, я думаю, нам нужно увидеть больше вашего тестового кода).
  • Переопределить mockSharedService.trigger_data в вашем тесте, используя: mockSharedService.trigger_data = of(true) (Примечание: если trigger_data является EventEmitter TypeScript не понравится, и вам может понадобиться: mockSharedService.trigger_data = of(true) as any)
  • Если вы хотите избежать приведения к любому из них, как я делал в предыдущем примере, вы можете использовать:
  const emitter = new EventEmitter();
  mockSharedService.trigger_data = emitter;
  emitter.emit(true);
  • Сделать trigger_data методом, который возвращает Observable и spyOn этого метода, используя spyOn(mockSharedService, 'trigger_data').and.returnValue(of(true)). Однако для этого также потребуется изменить реализацию triggerData на вызов trigger_data(), а не просто обращаться к ней как к свойству.

Я пытался протестировать функцию который содержит подписку на EventEmitter

Дополнительно, вы, вероятно, хотите использовать Subject вместо EventEmitter, EventEmitters используются Angular для их привязок Output. При реализации самих себя за пределами Angular мы можем использовать Subjects вместо EventEmitters (что фактически расширяет Subjects для целей Angular Outputs. См .: https://github.com/angular/angular/blob/master/packages/core/src/event_emitter.ts#L64)

1 голос
/ 19 апреля 2020

Вместо того, чтобы шпионить за методом подписки, шпионите за 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.
    }));
  });
...