如果 TestBed.inject() 或 TestBed.get()(已弃用)之前有 运行,则 TestBed.OverrideProvider() 不起作用

TestBed.OverrideProvider() doesn't work if TestBed.inject() or TestBed.get() (deprecated) has run before

给出下面的示例规格测试

beforeEach(function () {
        TestBed.configureTestingModule({
            providers: [
                { provide: TranslateService, useClass: TranslateServiceMock },
                { provide: StoreService, useClass: StoreServiceMock },
                {
                    provide: GLOBAL_CONFIG_TOKEN,
                    useValue: { default: true }
                }
            ],
        });
        let config = TestBed.inject(GLOBAL_CONFIG_TOKEN);
});

it('should override provider otherwise what is the point? :)', () => {
  let config = TestBed.overrideProvider(GLOBAL_CONFIG_TOKEN, { useValue: { default: false, random: 'damn' } });
expect(config).toEqual({default: false, random: 'damn'});
});

问题是测试失败了,因为 default 总是 truerandom 不是一个 属性 的配置。这意味着在测试模块的配置过程中配置仍然具有默认值并且提供者没有被覆盖。

知道为什么吗? overrideProvider 方法只是一个更新最初在 configureTestingModule 传递的 moduleRef 对象的助手吗?

似乎 TestBed.inject 是 运行ning 在 TestBed.overrideProvider 之前overrideProvider 没有任何效果。 overrideProvider 函数应该在 TestBed.inject() 之前使用。显然,这似乎只是 configurTestingModule() 函数 运行 之后的辅助方法。因此,上述示例的解决方案是:

beforeEach(function () {
        TestBed.configureTestingModule({
            providers: [
                { provide: TranslateService, useClass: TranslateServiceMock },
                { provide: StoreService, useClass: StoreServiceMock },
                {
                    provide: GLOBAL_CONFIG_TOKEN,
                    useValue: { default: true }
                }
            ],
        });
});

it('should override provider otherwise what is the point? :)', () => {
  TestBed.overrideProvider(GLOBAL_CONFIG_TOKEN, { useValue: { default: false, random: 'damn' } });

  let config = TestBed.inject(GLOBAL_CONFIG_TOKEN);
  expect(config).toEqual({default: false, random: 'damn'});
});

没错,因为有触发编译测试模块的内置函数。如果你想在需要重置 testBed 后更新该值,它只能通过访问私有属性来实现,因此不推荐,最好是在先创建 env 时编写适当的测试,然后再获取其数据。

尽管如此,您还是可以在 TestBed.overrideProvider 之前执行此操作以使其正常工作。

  (getTestBed() as any)._instantiated = false;
  (getTestBed() as any)._moduleFactory = undefined;