From a1d0f1e5d2d99446bf6dbc512a3f611c0eb72902 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Tue, 12 Nov 2019 09:20:36 -0800 Subject: [PATCH] fix(ivy): align TestBed.overrideProvider with what happens with providers in TestBed providers array (#33769) In Ivy, if you do: `TestBed.configureTestingModule({providers: [{provide: Service}]});` the injector will attempt to inject Service as if it was simply listed in the providers array like `{providers: [Service]}` This fixes an inconsistency when similarly providing an override with no `useValue` or `useFactory`. PR Close #33769 --- packages/core/test/test_bed_spec.ts | 13 ++++++++++++ .../core/testing/src/r3_test_bed_compiler.ts | 21 ++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/core/test/test_bed_spec.ts b/packages/core/test/test_bed_spec.ts index 160cd24b28..7c4ab3bf25 100644 --- a/packages/core/test/test_bed_spec.ts +++ b/packages/core/test/test_bed_spec.ts @@ -989,4 +989,17 @@ describe('TestBed', () => { .toEqual(originalResolver); }); }); + + onlyInIvy('VE injects undefined when provider does not have useValue or useFactory') + .describe('overrides provider', () => { + it('with empty provider object', () => { + @Injectable() + class Service { + } + TestBed.overrideProvider(Service, {}); + // Should be able to get a Service instance because it has no dependencies that can't be + // resolved + expect(TestBed.inject(Service)).toBeDefined(); + }); + }); }); diff --git a/packages/core/testing/src/r3_test_bed_compiler.ts b/packages/core/testing/src/r3_test_bed_compiler.ts index 5c35e420ef..f4296ed733 100644 --- a/packages/core/testing/src/r3_test_bed_compiler.ts +++ b/packages/core/testing/src/r3_test_bed_compiler.ts @@ -158,14 +158,19 @@ export class R3TestBedCompiler { overrideProvider( token: any, provider: {useFactory?: Function, useValue?: any, deps?: any[], multi?: boolean}): void { - const providerDef = provider.useFactory ? - { - provide: token, - useFactory: provider.useFactory, - deps: provider.deps || [], - multi: provider.multi - } : - {provide: token, useValue: provider.useValue, multi: provider.multi}; + let providerDef: Provider; + if (provider.useFactory !== undefined) { + providerDef = { + provide: token, + useFactory: provider.useFactory, + deps: provider.deps || [], + multi: provider.multi + }; + } else if (provider.useValue !== undefined) { + providerDef = {provide: token, useValue: provider.useValue, multi: provider.multi}; + } else { + providerDef = {provide: token}; + } const injectableDef: InjectableDef|null = typeof token !== 'string' ? getInjectableDef(token) : null;