[英]How to mock module which depends implicitly per test in Jest?
我有一个集成测试,我对 MongoDB 数据库进行了实际的 DB 调用。 但是为了测试事务是否过期,我需要为该特定 test 模拟数据库。 我进行实际数据库调用的原因有很多,我只是为了这个例子才提到状态。
Jest 具有jest.doMock
函数,但这仅在我想在测试中导入该函数时有用,但在我的情况下,这是我想在快速中间件中调用时为该特定测试模拟的 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"
}
});
});
})
对于这种情况,集成测试是多余的。 简单的单元测试就足够了。 它们执行起来很快,只测试一件事,你应该有很多。
因为您将处理程序定义为匿名函数,所以默认情况下很难进行单元测试。 所以第一个动作是通过提取它更容易测试。
// deduct-balance-handlers.ts
export const deductBalanceByTransaction = async (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.ts
import express from "express"
import db from "../db";
import { deductBalanceByTransaction } from './deduct-balance-handlers';
const app = express()
app.get("/api/deduct-balance/:txn_id", deductBalanceByTransaction);
现在可以轻松地在测试中重用处理程序,而无需依赖 Web 框架或数据库。
// a.test.ts
import db from "../db";
import { deductBalanceByTransaction } from './deduct-balance-handlers';
jest.mock('../db');
describe("deduct-balance", () => {
test("Expired transaction should respond with 401 status", async () => {
const response = mockResponse();
deductBalanceByTransaction(request, response);
expect(response.status).toBe(401);
});
})
为简单起见,我在代码中留下了创建模拟响应和模拟模块的部分。 可以在此处了解有关嘲笑的更多信息: https : //jestjs.io/docs/en/manual-mocks
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.