我在测试下面的课时遇到了一些问题。
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
我可以看到正确记录的电话。只有当测试结束时,数字才是错误的。
感谢您的任何帮助!
解决方案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()
有机会运行。