You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:27:28