间谍 returns callcount 0 当用作对象时 属性

Spy returns callcount 0 when used as object property

我正在尝试编写测试以检查是否调用了第三方库函数。

测试:(mocha)

describe('SomeClassTest', () => {
  describe('Setup', () => {
    beforeEach(() => {
      const channel = {createChannel: () => 'channel created'};
      // @ts-ignore
      this.channelSpy = Sinon.spy(channel, 'createChannel');
      // @ts-ignore
      Sinon.stub(amqplib, 'connect').returns(channel);
  });
    // @ts-ignore
    afterEach(() => amqplib.connect.restore());

    it('Should check if SomeClass has created Channel', () => {
      const someclass = SomeClass.getInstance();
      someclass.init();

      // @ts-ignore
      expect(amqplib.connect.callCount).to.be.eq(1); // True
      // @ts-ignore
      expect(this.channelSpy.callCount).to.be.eq(1); // False :(
    });
  });
});

class:

export default class SomeClass {

  private connection?: amqplib.Connection;

  public async init() {
    await this.connect();
    await this.createChannel();
  }

  private async connect(): Promise<void> {
    this.connection = await amqplib.connect(this.connectionOptions);
  }

  private async createChannel(): Promise<void> {
    if (!this.connection) {
      throw new Error('Some Error :)');
    }
    this.channel = await this.connection.createChannel();
  }
}

我确定 this.connection.createChannel() 已被调用,但测试不想证明这一点,有人能帮助我可怜的灵魂吗?:)

Promise 解析时,回调在 PromiseJobs queue 中排队,在当前 运行ning 消息完成 后处理

在这种情况下,您的函数在 PromiseJobs 中排队回调,当前 运行ning 消息是测试本身,因此测试运行s 完成在 PromiseJobs 中排队的作业有机会 运行 之前。

因为 PromiseJobs 中的作业还没有 运行,所以当它到达 channelSpy 的测试时测试失败,因为它还没有被调用。


init 返回的 Promise 已经链接到 connectcreateChannel 返回的 Promises 所以你所要做的就是让你的测试函数 async,然后在 init:

返回的 Promise 上调用 await
it('Should check if SomeClass has created Channel', async () => {  // async test function
  const someclass = SomeClass.getInstance();
  await someclass.init();  // await the Promise returned by init

  // @ts-ignore
  expect(amqplib.connect.callCount).to.be.eq(1); // True
  // @ts-ignore
  expect(this.channelSpy.callCount).to.be.eq(1); // True
});