Jest:在Promise中测试递归调用

问题描述 投票:2回答:1

我在测试下面的课时遇到了一些问题。

interface Connector {
   connect: () => Promise<void>;
}

class Unit {
   private connector: Connector;

   constructor(connector: Connector) {
      this.connector = connector;
   }

   public attemptConnect(iteration: number, max: number): void {
      console.log("attempt" + iteration);

      this.connector.connect()
         .then(() => {
            console.log("connected");
         })
         .catch((error) => {
            if (iteration < max) {
               this.attemptConnect(iteration + 1, max);
            }
         });
   }
}

我想测试Connector.connect()函数被调用适当的次数。我正试图通过以下方式实现这一点:

describe("Unit", () => {
   it("fails to record more than one recursion", async () => {
      const connector: Connector = {
         connect: jest.fn().mockRejectedValue(new Error("foo")),
      };
      const unit: Unit = new Unit(connector);

      await unit.attemptConnect(1, 4);

      expect((connector.connect as jest.Mock).mock.calls.length).toBe(4);
   });
});

不幸的是,expect()调用失败了

Error: expect(received).toBe(expected) // Object.is equality

Expected: 4
Received: 1

如果我使用调试器并观察值

(connector.connect as jest.Mock).mock.calls.length

我可以看到正确记录的电话。只有当测试结束时,数字才是错误的。

感谢您的任何帮助!

typescript unit-testing mocking jestjs
1个回答
2
投票

解决方案1

attemptConnect()返回承诺:

public attemptConnect(iteration: number, max: number): Promise<void> {
  console.log("attempt" + iteration);

  return this.connector.connect()
    .then(() => {
      console.log("connected");
    })
    .catch((error) => {
      if (iteration < max) {
        return this.attemptConnect(iteration + 1, max);
      }
    });
}

解决方案2

await测试中所需的事件循环周期数:

describe("Unit", () => {
  it("fails to record more than one recursion", async () => {
    const connector: Connector = {
      connect: jest.fn().mockRejectedValue(new Error("foo")),
    };
    const unit: Unit = new Unit(connector);

    unit.attemptConnect(1, 4);

    // await enough event loop cycles for all the callbacks queued
    // by then() and catch() to run, in this case 5:
    await Promise.resolve().then().then().then().then();

    expect((connector.connect as jest.Mock).mock.calls.length).toBe(4);
  });
});

细节

测试等待attemptConnect(),但由于它没有返回任何东西,await没有任何东西,同步测试继续执行。 expect()then()排队的回调之前运行并且失败,catch()有机会运行。

© www.soinside.com 2019 - 2024. All rights reserved.