简体   繁体   English

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

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

Given the example spec test below给定下面的示例规范测试

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'});
});

the thing is that test failed because default is always true and random is not a property of config.问题是测试失败,因为默认值始终为随机不是配置的属性。 This means that config still has the default value during the configure of Testing Module and the provider hasn't been overridden.这意味着在配置测试模块期间 config 仍然具有默认值,并且提供程序没有被覆盖。

Any idea why?知道为什么吗? Is overrideProvider method just a helper that updates the moduleRef object initially passed at configureTestingModule? overrideProvider方法是否只是更新最初在 configureTestingModule 传递的moduleRef object 的助手?

That's right because there're built-in functions that trigger compilation of the test module.没错,因为有一些内置函数会触发测试模块的编译。 If you want to update the value after you need to reset the testBed, it's doable only via accessing private properties and therefore not recommended, better would be to write a proper test when env is created first and then its data is fetched.如果您想在需要重置 testBed 后更新该值,则只能通过访问私有属性来实现,因此不推荐,最好在先创建 env 然后获取其数据时编写适当的测试。

Nevertheless that's what you can do before TestBed.overrideProvider to make it work.尽管如此,您可以在TestBed.overrideProvider之前执行此操作以使其正常工作。

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

As it seems the fact that TestBed.inject is running before TestBed.overrideProvider causes overrideProvider to not have any effect.似乎TestBed.injectTestBed.overrideProvider之前运行的事实导致 overrideProvider 没有任何效果。 The overrideProvider function should be used before TestBed.inject().应在 TestBed.inject() 之前使用 overrideProvider function。 Apparently it seems that is just a helper method after configurTestingModule() function run.显然,这似乎只是 configurTestingModule() function 运行后的辅助方法。 So a solution to the example above would be:因此,上述示例的解决方案是:

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'});
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM