@Output() EventEmitter 在测试时不发射

@Output() EventEmitter does not emit when testing

我有以下代码

it('should emit Sound on save', () => {
    spyOn(component, 'getBase64').and.returnValue(Promise.resolve({
      then(onFulfill, onReject) { onFulfill('fulfilled!'); }
    }));
    spyOn(component, 'saveRecordedData').and.callThrough();
    spyOn(component.recorded, 'emit');
    component.isRecording = false;
    component.blobUrl = {data: 'somedata'};
    fixture.detectChanges();
    saveBtn = fixture.debugElement.query(By.css('.fa-send')).triggerEventHandler('click', null);
    fixture.detectChanges();
    expect(component.saveRecordedData).toHaveBeenCalled();
    expect(component.getBase64).toHaveBeenCalledTimes(1);
    expect(component.recorded.emit).toHaveBeenCalled();
  });

测试以下代码

  saveRecordedData() {
    this.getBase64(this.blob).then((s: string) => {
      const sound: Sound = {base64: s, mimeType: this.mimeType};
      this.recorded.emit(sound);
    });
  }

问题是在测试中出现错误:SoundRecorderComponent > should emit on save

更新:如果我把期望写成如下

 expect(component.saveRecordedData).toHaveBeenCalled();
 expect(component.getBase64).toHaveBeenCalledTimes(1);
 component.recorded.emit({base64: 's', mimeType: 'a'});
 expect(component.recorded.emit).toHaveBeenCalled();

测试通过 :) : 所以我假设 eventemitter 有效?

我相信this.recorded.emit(sound);不叫。

为什么 this.recorded.emit(sound); 没有被调用?

已解决

此代码有效

it('should emit Sound on save', async () => {
    spyOn(component, 'getBase64').and.returnValue(Promise.resolve({
      then(onFulfill, onReject) { onFulfill('fulfilled!'); }
    }));
    spyOn(component, 'saveRecordedData').and.callThrough();
    spyOn(component.recorded, 'emit');
    component.isRecording = false;
    component.blobUrl = {data: 'somedata'};
    fixture.detectChanges();
    saveBtn = fixture.debugElement.query(By.css('.fa-send')).triggerEventHandler('click', null);
    fixture.detectChanges();
    fixture.whenStable().then(res => {
      expect(component.saveRecordedData).toHaveBeenCalled();
      expect(component.getBase64).toHaveBeenCalledTimes(1);
      expect(component.recorded.emit).toHaveBeenCalled();
    });
  });

注意:添加了asyncfixture.whenStable()

它之所以会发生,是因为 promises 给您的代码带来了异步性,并且断言在 promise.then 回调之前被调用。您可以做的最简单的事情是返回 thennable obj,而不是承诺。

spyOn(component, 'getBase64').and.returnValue({
      then(onFulfill, onReject) { onFulfill('fulfilled!'); }
});

我在这里删除了Promise.resolve