Jest测试Lambda入口时如何断言文件内部Usecase实例方法被调用?
问题根因
你的猜测是正确的:index.test.ts 中手动创建的 Usecase 实例,和 index.ts 模块初始化时内部创建的实例是完全独立的两个对象,因此你监听测试文件内创建的实例方法调用,自然统计不到业务代码里的调用记录。
解决方案(无需依赖注入,仅用 Jest 原生能力即可实现)
Jest 对类的模拟会自动记录所有实例化行为,所有通过 mock 类创建的实例都会保存在类构造函数的 mock.instances 属性中,你可以直接通过该属性获取 index.ts 内部创建的实例,修改后的测试代码如下:
// index.test.ts import { handler } from "../../../src/index"; import Usecase from "../../../src/usecase"; // 对Usecase类做全局mock,所有new Usecase的操作都会生成带mock方法的实例 jest.mock("../../../src/usecase"); // 做类型断言,方便调用mock类的专属属性 const MockUsecase = Usecase as jest.MockedClass<typeof Usecase>; describe("Test", () => { it("should call submitTaxes when handler is triggered", async () => { // GIVEN const event = {}; // 替换为你的实际入参 // 每次测试前清空mock调用记录,避免用例互相干扰 MockUsecase.mockClear(); // WHEN await handler(event); // THEN // 先验证Usecase类被正确实例化 expect(MockUsecase).toHaveBeenCalledTimes(1); // 从mock实例列表中获取index.ts内部创建的实例 const internalUsecase = MockUsecase.mock.instances[0] as jest.Mocked<Usecase>; // 验证实例方法被调用 expect(internalUsecase.submitTaxes).toHaveBeenCalledTimes(1); }); });
多测试用例隔离方案
如果你的测试文件包含多个用例,需要避免模块缓存导致 index.ts 内的 Usecase 实例被复用,可以使用 jest.resetModules() 配合动态导入实现每次用例都重新初始化模块:
describe("Test", () => { it("should call submitTaxes when handler is triggered", async () => { // GIVEN const event = {}; // 清空模块缓存 jest.resetModules(); jest.mock("../../../src/usecase"); // 动态导入依赖,每次都会重新执行index.ts的初始化逻辑 const { handler } = require("../../../src/index"); const MockUsecase = require("../../../src/usecase").default as jest.MockedClass<typeof Usecase>; // WHEN await handler(event); // THEN expect(MockUsecase).toHaveBeenCalledTimes(1); expect(MockUsecase.mock.instances[0].submitTaxes).toHaveBeenCalledTimes(1); }); });
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

