使用 ts-jest/utils 模拟数据库 Jest

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)

sli*_*wp2 8

用于jest.mock()模拟db模块。由于您是从模块范围调用该getDbConnection函数,因此需要getDbConnection在导入测试代码之前进行模拟。因为模块范围内的代码将在模块导入后立即执行。

\n

模拟的辅助函数:

\n
\n

根据其源的类型,提供模拟模块甚至其深层方法的类型。

\n
\n

它只提供 TS 的类型,而不是模拟模块(jest.mock()这有效吗)。

\n

此外,从全球文档中,我们知道:

\n
\n

在您的测试文件中,Jest 将每个方法和对象放入全局环境中。您无需要求或导入任何内容即可使用它们。但是,如果您更喜欢显式导入,则可以 import {describe,expect,test} from \'@jest/globals\'

\n
\n

例如

\n

db.ts

\n
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;\n
Run Code Online (Sandbox Code Playgroud)\n

controller.ts

\n
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 };\n
Run Code Online (Sandbox Code Playgroud)\n

controller.spec.ts

\n
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});\n
Run 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\n
Run Code Online (Sandbox Code Playgroud)\n