Search code examples
angularunit-testingkarma-jasminetestbed

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.

Any idea why? Is overrideProvider method just a helper that updates the moduleRef object initially passed at configureTestingModule?


Solution

  • 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.

    Nevertheless that's what you can do before TestBed.overrideProvider to make it work.

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