【发布时间】:2020-10-26 16:33:06
【问题描述】:
我有一个集成测试,我在其中对 MongoDB 数据库进行实际的 DB 调用。但为了测试事务是否过期,我需要为特定测试模拟数据库。我进行实际数据库调用的原因有很多,我只是为了这个例子而提到状态。
Jest 有 jest.doMock 函数,但这仅在我想在测试中导入函数时才有用,但在我的情况下,它是我想在 express 中间件内部调用时为特定测试模拟的 DB 函数.
还有另一个选项可以模拟整个 ../db 模块,但这会使我的实际项目中的测试变得非常复杂。如果我可以模拟特定测试的数据库调用,其余的所有测试都应该进行真正的数据库调用,这对我来说会很容易。
有没有办法在 Jest 中做到这一点?
// a.ts
import express from "express"
import db from "../db";
const app = express()
app.get("/api/deduct-balance/:txn_id", (req, res) => {
const txn = await db.findById(txn_id)
// return error message if txn expired
if (txn.exipre_at <= new Date()) {
return res.status(401).json({ error: "txn expired" });
}
// otherwise update the txn state
txn.state = "DEDUCTED";
await txn.save()
return res.status(200).json();
});
// a.test.ts
import db from "../db";
describe("mixed tests", () => {
test("should make REAL db calls", async () => {
await axios.get("/api/deduct-balance/123")
const txn = await db.findById("123");
expect(txn.state).toBe("DEDUCTED");
});
test("should use MOCKED value", async () => {
// need a way to mock the DB call so that I can return an expired transaction
// when I hit the API
const { data } = await axios.get("/api/deduct-balance/123")
expect(data).toBe({
error: {
message: "txn expired"
}
});
});
})
【问题讨论】:
-
这类测试最好不要作为集成测试来完成。如果您想测试请求处理程序的行为,您应该模拟所有依赖项以创建可预测和可重复的测试。模块
db应该是一个完整的模拟,findById应该返回一个模拟事务等等...... -
@Bart 那么我应该做哪种类型的测试作为集成测试?有兴趣知道您对此有何看法。
-
我留下了关于一般要点的答案。不幸的是,我不得不去,但我可以在稍后阶段扩展我的答案以使其更清楚。
标签: javascript typescript testing jestjs integration-testing