col*_*suz 3 unit-testing node.js jestjs ts-jest
我试图模拟数据库调用,但它一直导致db函数返回未定义。
请看一下我的文件。
数据库ts
import * as mysql from "mysql";
import * as util from "util";
{... other functions with named exports}
const getDbConnection = () => {
const pool = mysql.createPool(DB_CONFIG);
return {
query(sql: string) {
return util.promisify(pool.query).call(pool, sql);
},
};
};
export default getDbConnection;
Run Code Online (Sandbox Code Playgroud)
测试名称.spec.ts
import { mocked } from "ts-jest/utils";
import db from "../src/utils/db";
jest.mock("../src/utils/db");
describe("Test Controller", () => {
afterAll(() => {
jest.resetAllMocks();
});
mocked(db);
it("should retrieve all", async () => {
await request(app)
.get("/data")
.expect(200)
.expect(function (res) {
expect(res.body.data).toContain("data");
});
});
});
Run Code Online (Sandbox Code Playgroud)
控制器.ts
import getDbConnection from "../utils/db";
const db = getDbConnection();
router.get("/", async (_, res) => {
let sql = "...";
try {
let result = await db.query(sql);
res.status(200).json(result);
} catch (error) {
console.log("DB error", error);
}
});
Run Code Online (Sandbox Code Playgroud)
我还使用显式导入来开玩笑
import { expect, describe, it, jest, afterAll } from "@jest/globals";
Run Code Online (Sandbox Code Playgroud)
用于jest.mock()模拟db模块。由于您是从模块范围调用该getDbConnection函数,因此需要getDbConnection在导入测试代码之前进行模拟。因为模块范围内的代码将在模块导入后立即执行。
模拟的辅助函数:
\n\n\n根据其源的类型,提供模拟模块甚至其深层方法的类型。
\n
它只提供 TS 的类型,而不是模拟模块(jest.mock()这有效吗)。
此外,从全球文档中,我们知道:
\n\n\n在您的测试文件中,Jest 将每个方法和对象放入全局环境中。您无需要求或导入任何内容即可使用它们。但是,如果您更喜欢显式导入,则可以 import {describe,expect,test} from \'@jest/globals\'
\n
例如
\ndb.ts:
import * as mysql from \'mysql\';\nimport * as util from \'util\';\n\nconst DB_CONFIG = {};\n\nconst getDbConnection = () => {\n const pool = mysql.createPool(DB_CONFIG);\n return {\n query(sql: string) {\n return util.promisify(pool.query).call(pool, sql);\n },\n };\n};\nexport default getDbConnection;\nRun Code Online (Sandbox Code Playgroud)\ncontroller.ts:
import getDbConnection from \'./db\';\nimport express from \'express\';\n\nconst app = express();\nconst db = getDbConnection();\n\napp.get(\'/\', async (_, res) => {\n let sql = \'select * from users\';\n\n try {\n let result = await db.query(sql);\n res.status(200).json(result);\n } catch (error) {\n console.log(\'DB error\', error);\n }\n});\n\nexport { app };\nRun Code Online (Sandbox Code Playgroud)\ncontroller.spec.ts:
import request from \'supertest\';\nimport { mocked } from \'ts-jest/utils\';\nimport getDbConnection from \'./db\';\n\njest.mock(\'./db\');\n\nconst mGetDbConnection = mocked(getDbConnection);\n\ndescribe(\'68825658\', () => {\n afterAll(() => {\n jest.resetAllMocks();\n });\n it(\'should retrieve all\', async () => {\n const mDB = {\n query: jest.fn().mockResolvedValueOnce(\'data\'),\n };\n mGetDbConnection.mockReturnValueOnce(mDB);\n\n const { app } = require(\'./controller\');\n await request(app)\n .get(\'/\')\n .expect(200)\n .expect((res) => {\n expect(res.body).toEqual(\'data\');\n });\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n测试结果:
\n\n PASS examples/68825658/controller.spec.ts (10.715 s)\n 68825658\n \xe2\x9c\x93 should retrieve all (434 ms)\n\n---------------|---------|----------|---------|---------|-------------------\nFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n---------------|---------|----------|---------|---------|-------------------\nAll files | 80 | 100 | 50 | 78.95 | \n controller.ts | 91.67 | 100 | 100 | 90.91 | 14 \n db.ts | 62.5 | 100 | 0 | 62.5 | 7-10 \n---------------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests: 1 passed, 1 total\nSnapshots: 0 total\nTime: 11.624 s\nRun Code Online (Sandbox Code Playgroud)\n