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

升级Inversify从v6到v7.5后测试失败,容器在部分用例中绑定失效

升级Inversify从v6到v7.5后测试失败,容器在部分用例中绑定失效

嘿,看起来你在把Inversify从v6升级到v7.5之后,遇到了测试里容器绑定失效的问题——大部分类似的测试都正常,唯独WirelineStore的绑定在测试运行时抛出TypeError。我帮你梳理下可能的原因和解决办法:

问题现象回顾

测试套件运行时触发以下错误,指向WirelineStore的绑定行:

TypeError 
37 | container.bind<IFracStore>(FracStoreType).to(FracStore);
38 | container.bind<IStagesStore>(StagesStoreType).to(StagesStore);
> 39 | container.bind<IWirelineStore>(WirelineStoreType).to(WirelineStore);
    | ^

可能的原因分析

Inversify从v6到v7.x做了不少API和类型检查的升级,结合你的测试代码和配置,大概率是这几个点出了问题:

  • 错误使用异步await调用rebind:Inversify的rebind方法本身是同步的,v6可能对异步调用的兼容性更强,但v7里如果await一个同步方法,会拿到undefined,后续调用toConstantValue会导致容器状态异常,进而影响后续的绑定操作。
  • 容器状态跨测试污染:多个测试共用同一个容器实例,前一个测试的rebind操作修改了容器状态,导致后续测试的绑定失效。
  • 类型检查更严格:v7对泛型绑定的类型校验更严格,如果WirelineStore没有正确实现IWirelineStore接口,会触发绑定错误。

具体解决办法

1. 移除rebind前的await

看你测试里的beforeAll代码,把多余的await去掉:

beforeAll(() => {
  // 去掉await,因为rebind是同步方法
  container.rebind(serviceType.OverviewData).toConstantValue(dataService);
  container.rebind(serviceType.YAxisSettings).toConstantValue({ get: mockYSettingsGet, update: mockYSettingsUpdate });
});

之前的await会让你拿到undefined,调用toConstantValue时会静默失败(因为你mock了console.error),导致容器内部状态混乱,最终在绑定WirelineStore时抛出错误。

2. 测试前重置容器状态

如果多个测试共用同一个容器实例,建议在每个测试前重置容器,避免状态污染:

beforeEach(() => {
  // 清空所有现有绑定
  container.unbindAll();
  // 重新初始化所有基础绑定(和你容器模块里的绑定代码一致)
  container.bind<IFracStore>(FracStoreType).to(FracStore);
  container.bind<IStagesStore>(StagesStoreType).to(StagesStore);
  container.bind<IWirelineStore>(WirelineStoreType).to(WirelineStore);
  container.bind<IStatsStore>(StatsStoreType).to(StatsStore);
  container.bind<IDashboardStore>(DashboardStoreType).to(DashboardStore);
  container.bind<IMonitorsAndAlarmsStore>(MonitorsAndAlarmsStoreType).to(MonitorsAndAlarmsStore);
  
  // 再rebind测试需要的mock服务
  container.rebind(serviceType.OverviewData).toConstantValue(dataService);
  container.rebind(serviceType.YAxisSettings).toConstantValue({ get: mockYSettingsGet, update: mockYSettingsUpdate });
  
  // 其他测试初始化逻辑
  store = new WirelineStore();
  const mockApi = { getInstance: jest.fn().mockImplementation(() => ({})) };
  (DataStoreApi as unknown as jest.Mock).mockImplementation(() => mockApi);
  (<any>store).dataStoreApi = { buildDataSourcesFromPad: mockBuildDataSourcesFromPad.mockReturnValue([{ id: 1, site_slug: '2' }]) };
  mockGet.mockImplementation(() => []);
  jest.spyOn(console, 'error');
  (console.error as any).mockImplementation(() => {});
});

3. 验证WirelineStore的接口实现

确保WirelineStore类正确实现了IWirelineStore接口,在类定义上加上implements IWirelineStore,让TypeScript编译器帮你检查是否有遗漏的方法或属性:

class WirelineStore implements IWirelineStore {
  // 类实现代码
}

v7的类型检查更严格,哪怕是一个可选属性未实现,都可能导致绑定失败。

4. 确认容器是单例实例

检查你的container模块是否导出的是单例实例,比如:

// src/container.ts
import { Container } from 'inversify';

const container = new Container();
// 绑定代码...
export default container;

如果是每次导入都创建新容器,那测试里的rebind操作不会影响到绑定代码里的容器实例,也会导致绑定失效。

验证步骤

  1. 先移除beforeAll里的await,运行测试看是否解决问题;
  2. 如果还是失败,检查WirelineStore的接口实现;
  3. 最后尝试在beforeEach里重置容器状态,确保每个测试都有干净的容器环境。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:38:09