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
This commit is contained in:
Andrew Scott 2019-11-12 09:20:36 -08:00 committed by Andrew Kushnir
parent a12b5f930a
commit a1d0f1e5d2
2 changed files with 26 additions and 8 deletions

View File

@ -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();
});
});
});

View File

@ -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<any>|null =
typeof token !== 'string' ? getInjectableDef(token) : null;