typescript - 笑话:在 Promise 中测试递归调用
问题描述
我在测试以下课程时遇到了一些问题。
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()
有机会运行之前运行和失败。
推荐阅读
- java - 无法将 JTextField 输入转换为整数
- c# - 使用 C# 打开 Outlook 模板文件
- spotfire - 如何在 Spotfire 中将 x 轴位置移动到顶部
- regex - sh/sed 从文件中删除行以进行 docker-compose 卷覆盖
- groovy - 为什么 Collections.unmodifiableCollection 允许您更改集合?
- python - 如何基于 django 的 Settings Module 编写测试
- javascript - 包含在多维数组中
- django - Django - 模板未显示我传递的整个上下文列表
- c++ - 在 CentOS 上安装 tcmalloc
- r - 安装 AER 但无法识别包“car”