如何验证间谍函数的结果(callThrough)

时间:2019-03-04 12:22:03

标签: node.js typescript jasmine nestjs

我想验证/确定间谍功能的结果。我正在使用茉莉的nestjs框架。我在要“侦听”的方法上创建了一个茉莉间谍,即监听args和响应/异常。但是,我无法访问间谍方法的返回值。

假设我有一个发射器和侦听器,并且我想断言在数据库操作失败时侦听器会引发异常。

监听器:

  onModuleInit() {
    this.emitter.on('documentDeleted', d => this.onDocumentDeleted(d));
  }

  @CatchAndLogAnyException()
  private async onDocumentDeleted(dto: DocumentDeletedEventDTO) {
    this.logger.log(`Deleting document with id '${dto.id}'...`);

    const result = await this.ResearchHearingTestModel.deleteOne({ _id: dto.id });
    if (!result.ok) {
      throw new DataAccessException(
        `Deleting document with id '${dto.id}' failed. Model.deleteOne(id) result: ${result}`,
      );
    }
    if (result.n < 1) {
      throw new DocumentNotFoundException(`Deleting document with id '${dto.id}' failed.`);
    }

    this.logger.log(`Deleted document with id '${dto.id}.`);
  }

测试:

      const mockId = 123;
      const spyDelete = spyOn(model, 'deleteOne').and.returnValue({ ok: 1, n: 0 });
      const spyOnDeleted = spyOn(listener, 'onDocumentDeleted');
      spyOnDeleted.and.callThrough();

      await emitter.emit('documentDeleted', new DocumentDeletedEventDTO(mockId));

      expect(spyOnDeleted).toHaveBeenCalledTimes(1);
      expect(spyDelete).toHaveBeenCalledTimes(1);
      expect(spyDelete).toHaveBeenCalledWith(expect.objectContaining({ _id: mockId }));
      expect(spyOnDeleted).toThrow(DocumentNotFoundException);

因此,在调试时,我可以看到spyOnDeleted["[[Scopes]]"][0].spy.calls.mostRecent["[[Scopes]]"][0].calls[0].returnValue是我一直在寻找的承诺,但我无法访问它或对其进行验证。

当我运行测试时,这是输出:

    expect(received).toThrow(expected)

    Expected name: "DocumentNotFoundException"

    Received function did not throw

       95 |       expect(spyDelete).toHaveBeenCalledTimes(1);
       96 |       expect(spyDelete).toHaveBeenCalledWith(expect.objectContaining({ _id: mockId }));
    >  97 |       expect(spyOnDeleted).toThrow(DocumentNotFoundException);
          |                            ^
       98 |     });
       99 |   });
      100 | });

我已经看到CallThrough injected spy和其他几个类似的问题,但我仍然希望可以监视callThrough方法并对其进行监听。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

toThrow不能用于间谍。您可以使用间谍来模拟行为,也可以使用callThrough使用实际行为,然后确保使用特定参数调用了该方法。但是间谍不会获得有关其产生的结果(值或错误)的信息,因此您无法对此设置期望。

如果要测试onDocumentDeleted的行为,则必须通过观察该方法的效果来间接测试它。在您的情况下(使用@CatchAndLogAnyException),似乎已写入日志!因此,您可以监视日志,并期望它与错误消息一起被调用。或者,您也可以通过公开将该方法直接进行测试。