Jest/TypeScript:在Jest和TypeScript中模拟包含私有成员的类依赖
解决方案:绕过TypeScript私有成员检查,模拟类A的公共方法
你遇到的问题本质是TypeScript的私有成员类型检查和Jest模拟逻辑的冲突——jest.Mocked<A>要求严格匹配类A的所有成员(包括私有成员),但私有成员在类外部无法被合法定义,所以触发了类型错误。好在类B的测试只依赖类A的getSomething公共方法,私有成员_baseClassImpl属于类A的内部实现细节,完全不需要在mock中体现。
下面是两种可行的解决方法:
方法1:直接用类型断言绕过私有成员检查
创建一个只包含getSomething mock函数的对象,通过as A断言它符合类A的类型。TypeScript会忽略私有成员的缺失,而运行时Jest的mock函数能正常响应类B的调用(因为类B根本不会访问私有成员)。
完整测试代码:
test("test functionOfClassBToTest", () => { // 定义getSomething的mock函数,指定返回值 const mockGetSomething = jest.fn().mockReturnValue("Mock value"); // 创建mockA,仅包含需要的方法,断言为A类型 const mockA = { getSomething: mockGetSomething } as A; const classBToTest = new B(mockA); const result = classBToTest.functionOfClassBToTest(); // 验证返回值符合预期 expect(result).toStrictEqual("Mock value"); // 验证mock函数确实被调用 expect(mockGetSomething).toHaveBeenCalled(); });
方法2:结合jest.Mocked<Partial<A>>增强类型提示
如果你想保留Jest mock的类型提示,可以先创建一个Partial<A>的mock对象,再通过双重断言转换为A类型:
test("test functionOfClassBToTest", () => { const mockGetSomething = jest.fn().mockReturnValue("Mock value"); const mockA = { getSomething: mockGetSomething } as jest.Mocked<Partial<A>> as A; const classBToTest = new B(mockA); expect(classBToTest.functionOfClassBToTest()).toBe("Mock value"); expect(mockGetSomething).toHaveBeenCalledTimes(1); });
关键逻辑说明
- 单元测试只需要关注公共API的交互:类B的方法仅调用类A的
getSomething,完全不涉及私有成员_baseClassImpl,所以mock对象不需要包含这个私有属性。 - 类型断言是安全的:这里的断言只是告诉TypeScript“信任这个对象符合A的类型”,而运行时Jest的mock函数能完美替代原方法的行为。
内容的提问来源于stack exchange,提问作者aniket singh
相关产品推荐
相关产品推荐

