如何在Jest测试中正确Mock TypeORM的QueryRunner.manager.findOne
问题
我正在测试一个接收QueryRunner作为参数、并执行queryRunner.manager.findOne的函数,核心代码如下:
const logistic = await queryRunner.manager.findOne(Logistic, { where: { id: logisticsId || scooterLogisticId, }, });
在Jest测试中,我已经Mock了data-source和database模块:
data-source模块原代码:
const dataSource = addTransactionalDataSource({ dataSource: new DataSource(ormConfig), patch: true, });
database模块原代码:
export const database = new DatabaseManager();
我的测试文件代码如下:
import { dataSource } from "../../../../data-source"; jest.mock("../../../../data-source"); jest.mock("../../../../helpers/database") describe("isScooter", () => { // Shared mock data const mockEmail = "test@example.com"; const mockParsedBody = { completedAt: new Date(), slotIdInbound: "DEF456", fees: [{ value: 10 }, { value: 20 }], inspectionNote: "Some inspection notes", agent: "John Doe", location: "San Francisco", productType: "scooter", }; let queryRunner: QueryRunner; beforeEach(async () => { queryRunner = dataSource.createQueryRunner(); }); afterEach(async () => { jest.clearAllMocks() }) // ... 其他测试代码 (queryRunner.manager.findOne as jest.Mock).mockResolvedValueOnce(mockLogistic3); });
但执行到(queryRunner.manager.findOne as jest.Mock).mockResolvedValueOnce(mockLogistic3);时,出现queryRunner未定义的错误,请问如何正确Mock并实例化QueryRunner?
解决方案
问题根源是你没有正确MockdataSource.createQueryRunner()的返回值,导致queryRunner实际为undefined。以下是正确的Mock步骤:
提前定义完整的Mock结构
先创建Mock的findOne方法、manager对象和QueryRunner实例,确保每个核心方法都是Jest Mock函数。指定createQueryRunner的返回值
在beforeEach中,明确让dataSource.createQueryRunner返回我们预定义的Mock QueryRunner对象。
修改后的测试代码示例:
import { dataSource } from "../../../../data-source"; import { QueryRunner } from "typeorm"; jest.mock("../../../../data-source"); jest.mock("../../../../helpers/database") // 预定义Mock组件 const mockFindOne = jest.fn(); const mockManager = { findOne: mockFindOne }; const mockQueryRunner = { manager: mockManager } as unknown as QueryRunner; describe("isScooter", () => { // Shared mock data const mockEmail = "test@example.com"; const mockParsedBody = { completedAt: new Date(), slotIdInbound: "DEF456", fees: [{ value: 10 }, { value: 20 }], inspectionNote: "Some inspection notes", agent: "John Doe", location: "San Francisco", productType: "scooter", }; let queryRunner: QueryRunner; beforeEach(async () => { // 绑定createQueryRunner的返回值 (dataSource.createQueryRunner as jest.Mock).mockReturnValue(mockQueryRunner); queryRunner = dataSource.createQueryRunner(); // 重置findOne的Mock状态,避免测试间污染 mockFindOne.mockReset(); }); afterEach(async () => { jest.clearAllMocks() }) test("your test case", async () => { // 设置findOne的返回值 mockFindOne.mockResolvedValueOnce(mockLogistic3); // 执行待测试函数并传入queryRunner const result = await yourTestFunction(queryRunner); // 断言findOne的调用逻辑 expect(mockFindOne).toHaveBeenCalledWith(Logistic, { where: { id: expect.any(String) } }); // 其他业务逻辑断言 }); });
- 关键注意事项
- 必须确保
dataSource.createQueryRunner的Mock返回值是结构完整的对象,而非默认的undefined - 单独维护
mockFindOne函数,便于在不同测试用例中灵活设置返回值和校验调用情况 - 在
beforeEach中重置Mock状态,避免测试用例之间的状态污染
- 必须确保
内容的提问来源于stack exchange,提问作者Rafael Polonio
相关产品推荐
相关产品推荐

