From 3aba7ebe6abbf78c470b45f4bd1f6f9f37a653b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ortiz=20Garc=C3=ADa?= Date: Mon, 19 Aug 2019 15:05:29 -0700 Subject: [PATCH] feat(core): Introduce TestBed.inject to replace TestBed.get (#32200) TestBed.get is not type safe, fixing it would be a massive breaking change. The Angular team has proposed replacing it with TestBed.inject and deprecate TestBed.get. Deprecation from TestBed.get will come as a separate commit. Issue #26491 Fixes #29905 BREAKING CHANGE: Injector.get now accepts abstract classes to return type-safe values. Previous implementation returned `any` through the deprecated implementation. PR Close #32200 --- aio/src/app/app.component.spec.ts | 2 +- packages/core/src/application_ref.ts | 3 +- packages/core/src/di/injector.ts | 5 +- .../test/render3/view_container_ref_spec.ts | 2 +- packages/core/testing/src/r3_test_bed.ts | 66 +++++++++----- packages/core/testing/src/test_bed.ts | 87 ++++++++++++------- packages/core/testing/src/test_bed_common.ts | 18 ++-- .../platform-server/test/integration_spec.ts | 10 +-- tools/public_api_guard/core/core.d.ts | 2 +- tools/public_api_guard/core/testing.d.ts | 16 ++-- 10 files changed, 132 insertions(+), 79 deletions(-) diff --git a/aio/src/app/app.component.spec.ts b/aio/src/app/app.component.spec.ts index 54b069ba84..9b6f2808da 100644 --- a/aio/src/app/app.component.spec.ts +++ b/aio/src/app/app.component.spec.ts @@ -677,7 +677,7 @@ describe('AppComponent', () => { }); it('should not be loaded/registered until necessary', () => { - const loader: TestElementsLoader = fixture.debugElement.injector.get(ElementsLoader); + const loader = fixture.debugElement.injector.get(ElementsLoader) as unknown as TestElementsLoader; expect(loader.loadCustomElement).not.toHaveBeenCalled(); setHasFloatingToc(true); diff --git a/packages/core/src/application_ref.ts b/packages/core/src/application_ref.ts index e87f10051c..0ae872145b 100644 --- a/packages/core/src/application_ref.ts +++ b/packages/core/src/application_ref.ts @@ -601,7 +601,8 @@ export class ApplicationRef { this.componentTypes.push(componentFactory.componentType); // Create a factory associated with the current module if it's not bound to some other - const ngModule = isBoundToModule(componentFactory) ? null : this._injector.get(NgModuleRef); + const ngModule = + isBoundToModule(componentFactory) ? undefined : this._injector.get(NgModuleRef); const selectorOrNode = rootSelectorOrNode || componentFactory.selector; const compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule); diff --git a/packages/core/src/di/injector.ts b/packages/core/src/di/injector.ts index cecd9cf15b..df9023dac8 100644 --- a/packages/core/src/di/injector.ts +++ b/packages/core/src/di/injector.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Type} from '../interface/type'; +import {AbstractType, Type} from '../interface/type'; import {stringify} from '../util/stringify'; import {resolveForwardRef} from './forward_ref'; @@ -55,7 +55,8 @@ export abstract class Injector { * @returns The instance from the injector if defined, otherwise the `notFoundValue`. * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`. */ - abstract get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): T; + abstract get( + token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; /** * @deprecated from v4.0.0 use Type or InjectionToken * @suppress {duplicate} diff --git a/packages/core/test/render3/view_container_ref_spec.ts b/packages/core/test/render3/view_container_ref_spec.ts index c713f4d97e..633c808a24 100644 --- a/packages/core/test/render3/view_container_ref_spec.ts +++ b/packages/core/test/render3/view_container_ref_spec.ts @@ -299,7 +299,7 @@ describe('ViewContainerRef', () => { const changeDetector = ref.injector.get(ChangeDetectorRef); changeDetector.detectChanges(); expect(dynamicComp.doCheckCount).toEqual(1); - expect(changeDetector.context).toEqual(dynamicComp); + expect((changeDetector as any).context).toEqual(dynamicComp); }); it('should not throw when destroying a reattached component', () => { diff --git a/packages/core/testing/src/r3_test_bed.ts b/packages/core/testing/src/r3_test_bed.ts index c14143aa36..88b97e174d 100644 --- a/packages/core/testing/src/r3_test_bed.ts +++ b/packages/core/testing/src/r3_test_bed.ts @@ -11,6 +11,7 @@ // this statement only. // clang-format off import { + AbstractType, Component, Directive, InjectFlags, @@ -49,7 +50,7 @@ const UNDEFINED: Symbol = Symbol('UNDEFINED'); * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3` * according to the compiler used. */ -export class TestBedRender3 implements Injector, TestBed { +export class TestBedRender3 implements TestBed { /** * Initialize the environment for testing with a compiler factory, a PlatformRef, and an * angular module. These are common to every test in the suite. @@ -150,15 +151,26 @@ export class TestBedRender3 implements Injector, TestBed { return TestBedRender3 as any as TestBedStatic; } + static inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; + static inject( + token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T + |null; + static inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, + flags?: InjectFlags): T|null { + return _getTestBedRender3().inject(token, notFoundValue, flags); + } + + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ static get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; - /** - * @deprecated from v8.0.0 use Type or InjectionToken - */ + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ static get(token: any, notFoundValue?: any): any; + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ static get( token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, flags: InjectFlags = InjectFlags.Default): any { - return _getTestBedRender3().get(token, notFoundValue); + return _getTestBedRender3().inject(token, notFoundValue, flags); } static createComponent(component: Type): ComponentFixture { @@ -244,22 +256,33 @@ export class TestBedRender3 implements Injector, TestBed { compileComponents(): Promise { return this.compiler.compileComponents(); } - get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; - /** - * @deprecated from v8.0.0 use Type or InjectionToken - */ - get(token: any, notFoundValue?: any): any; - get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, - flags: InjectFlags = InjectFlags.Default): any { - if (token === TestBedRender3) { - return this; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T + |null; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, + flags?: InjectFlags): T|null { + if (token as unknown === TestBedRender3) { + return this as any; } const result = this.testModuleRef.injector.get(token, UNDEFINED, flags); return result === UNDEFINED ? this.compiler.injector.get(token, notFoundValue, flags) : result; } + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ + get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ + get(token: any, notFoundValue?: any): any; + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ + get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, + flags: InjectFlags = InjectFlags.Default): any { + return this.inject(token, notFoundValue, flags); + } + execute(tokens: any[], fn: Function, context?: any): any { - const params = tokens.map(t => this.get(t)); + const params = tokens.map(t => this.inject(t)); return fn.apply(context, params); } @@ -299,7 +322,7 @@ export class TestBedRender3 implements Injector, TestBed { } createComponent(type: Type): ComponentFixture { - const testComponentRenderer: TestComponentRenderer = this.get(TestComponentRenderer); + const testComponentRenderer = this.inject(TestComponentRenderer); const rootElId = `root-ng-internal-isolated-${_nextRootElementId++}`; testComponentRenderer.insertRootElement(rootElId); @@ -310,11 +333,12 @@ export class TestBedRender3 implements Injector, TestBed { `It looks like '${stringify(type)}' has not been IVY compiled - it has no 'ngComponentDef' field`); } - // TODO: Don't cast as `any`, proper type is boolean[] - const noNgZone = this.get(ComponentFixtureNoNgZone as any, false); - // TODO: Don't cast as `any`, proper type is boolean[] - const autoDetect: boolean = this.get(ComponentFixtureAutoDetect as any, false); - const ngZone: NgZone|null = noNgZone ? null : this.get(NgZone as Type, null); + // TODO: Don't cast as `InjectionToken`, proper type is boolean[] + const noNgZone = this.inject(ComponentFixtureNoNgZone as InjectionToken, false); + // TODO: Don't cast as `InjectionToken`, proper type is boolean[] + const autoDetect: boolean = + this.inject(ComponentFixtureAutoDetect as InjectionToken, false); + const ngZone: NgZone|null = noNgZone ? null : this.inject(NgZone, null); const componentFactory = new ComponentFactory(componentDef); const initComponent = () => { const componentRef = diff --git a/packages/core/testing/src/test_bed.ts b/packages/core/testing/src/test_bed.ts index 1c8b81ffa0..9f8692d836 100644 --- a/packages/core/testing/src/test_bed.ts +++ b/packages/core/testing/src/test_bed.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ApplicationInitStatus, CompilerOptions, Component, Directive, InjectFlags, InjectionToken, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵAPP_ROOT as APP_ROOT, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetInjectableDef as getInjectableDef, ɵivyEnabled as ivyEnabled, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify, ɵɵInjectableDef} from '@angular/core'; +import {AbstractType, ApplicationInitStatus, CompilerOptions, Component, Directive, InjectFlags, InjectionToken, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵAPP_ROOT as APP_ROOT, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetInjectableDef as getInjectableDef, ɵivyEnabled as ivyEnabled, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify, ɵɵInjectableDef} from '@angular/core'; import {AsyncTestCompleter} from './async_test_completer'; import {ComponentFixture} from './component_fixture'; @@ -56,16 +56,15 @@ export interface TestBed { compileComponents(): Promise; - get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T + |null; - // TODO: switch back to official deprecation marker once TSLint issue is resolved - // https://github.com/palantir/tslint/issues/4522 - /** - * deprecated from v8.0.0 use Type or InjectionToken - * This does not use the deprecated jsdoc tag on purpose - * because it renders all overloads as deprecated in TSLint - * due to https://github.com/palantir/tslint/issues/4522. - */ + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ + get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ get(token: any, notFoundValue?: any): any; execute(tokens: any[], fn: Function, context?: any): any; @@ -104,7 +103,7 @@ export interface TestBed { * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3` * according to the compiler used. */ -export class TestBedViewEngine implements Injector, TestBed { +export class TestBedViewEngine implements TestBed { /** * Initialize the environment for testing with a compiler factory, a PlatformRef, and an * angular module. These are common to every test in the suite. @@ -216,16 +215,29 @@ export class TestBedViewEngine implements Injector, TestBed { return TestBedViewEngine as any as TestBedStatic; } + static inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; + static inject( + token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T + |null; + static inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, + flags?: InjectFlags): T|null { + return _getTestBedViewEngine().inject(token, notFoundValue, flags); + } + + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ static get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; /** - * @deprecated from v8.0.0 use Type or InjectionToken + * TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject * @suppress {duplicate} */ static get(token: any, notFoundValue?: any): any; + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ static get( token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, flags: InjectFlags = InjectFlags.Default): any { - return _getTestBedViewEngine().get(token, notFoundValue, flags); + return _getTestBedViewEngine().inject(token, notFoundValue, flags); } static createComponent(component: Type): ComponentFixture { @@ -431,8 +443,7 @@ export class TestBedViewEngine implements Injector, TestBed { class DynamicTestModule { } - const compilerFactory: TestingCompilerFactory = - this.platform.injector.get(TestingCompilerFactory); + const compilerFactory = this.platform.injector.get(TestingCompilerFactory); this._compiler = compilerFactory.createTestingCompiler(this._compilerOptions); for (const summary of [this._testEnvAotSummaries, ...this._aotSummaries]) { this._compiler.loadAotSummaries(summary); @@ -454,16 +465,17 @@ export class TestBedViewEngine implements Injector, TestBed { } } - get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; - /** - * @deprecated from v8.0.0 use Type or InjectionToken - */ - get(token: any, notFoundValue?: any): any; - get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, - flags: InjectFlags = InjectFlags.Default): any { + inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T + |null; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, + flags?: InjectFlags): T|null { this._initIfNeeded(); - if (token === TestBed) { - return this; + if (token as unknown === TestBed) { + return this as any; } // Tests can inject things from the ng module and from the compiler, // but the ng module can't inject things from the compiler and vice versa. @@ -471,9 +483,19 @@ export class TestBedViewEngine implements Injector, TestBed { return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue, flags) : result; } + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ + get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ + get(token: any, notFoundValue?: any): any; + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ + get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, + flags: InjectFlags = InjectFlags.Default): any { + return this.inject(token, notFoundValue, flags); + } + execute(tokens: any[], fn: Function, context?: any): any { this._initIfNeeded(); - const params = tokens.map(t => this.get(t)); + const params = tokens.map(t => this.inject(t)); return fn.apply(context, params); } @@ -575,12 +597,13 @@ export class TestBedViewEngine implements Injector, TestBed { `Cannot create the component ${stringify(component)} as it was not imported into the testing module!`); } - // TODO: Don't cast as `any`, proper type is boolean[] - const noNgZone = this.get(ComponentFixtureNoNgZone as any, false); - // TODO: Don't cast as `any`, proper type is boolean[] - const autoDetect: boolean = this.get(ComponentFixtureAutoDetect as any, false); - const ngZone: NgZone|null = noNgZone ? null : this.get(NgZone as Type, null); - const testComponentRenderer: TestComponentRenderer = this.get(TestComponentRenderer); + // TODO: Don't cast as `InjectionToken`, declared type is boolean[] + const noNgZone = this.inject(ComponentFixtureNoNgZone as InjectionToken, false); + // TODO: Don't cast as `InjectionToken`, declared type is boolean[] + const autoDetect: boolean = + this.inject(ComponentFixtureAutoDetect as InjectionToken, false); + const ngZone: NgZone|null = noNgZone ? null : this.inject(NgZone, null); + const testComponentRenderer: TestComponentRenderer = this.inject(TestComponentRenderer); const rootElId = `root${_nextRootElementId++}`; testComponentRenderer.insertRootElement(rootElId); @@ -658,7 +681,7 @@ export function inject(tokens: any[], fn: Function): () => any { // Return an async test method that returns a Promise if AsyncTestCompleter is one of // the injected tokens. return testBed.compileComponents().then(() => { - const completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter); + const completer = testBed.inject(AsyncTestCompleter); testBed.execute(tokens, fn, this); return completer.promise; }); diff --git a/packages/core/testing/src/test_bed_common.ts b/packages/core/testing/src/test_bed_common.ts index 981a5421b3..764000075f 100644 --- a/packages/core/testing/src/test_bed_common.ts +++ b/packages/core/testing/src/test_bed_common.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Component, Directive, InjectFlags, InjectionToken, NgModule, Pipe, PlatformRef, SchemaMetadata, Type} from '@angular/core'; +import {AbstractType, Component, Directive, InjectFlags, InjectionToken, NgModule, Pipe, PlatformRef, SchemaMetadata, Type} from '@angular/core'; import {ComponentFixture} from './component_fixture'; import {MetadataOverride} from './metadata_override'; @@ -114,15 +114,15 @@ export interface TestBedStatic { deps?: any[], }): TestBedStatic; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; + inject( + token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T + |null; + + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; - // TODO: switch back to official deprecation marker once TSLint issue is resolved - // https://github.com/palantir/tslint/issues/4522 - /** - * deprecated from v8.0.0 use Type or InjectionToken - * This does not use the deprecated jsdoc tag on purpose - * because it renders all overloads as deprecated in TSLint - * due to https://github.com/palantir/tslint/issues/4522. - */ + /** TODO(goodwine): Mark as deprecated from v9.0.0 use TestBed.inject */ get(token: any, notFoundValue?: any): any; createComponent(component: Type): ComponentFixture; diff --git a/packages/platform-server/test/integration_spec.ts b/packages/platform-server/test/integration_spec.ts index b3e93f19d8..9b6bb35e96 100644 --- a/packages/platform-server/test/integration_spec.ts +++ b/packages/platform-server/test/integration_spec.ts @@ -776,7 +776,7 @@ class HiddenModule { const mock = ref.injector.get(HttpTestingController) as HttpTestingController; const http = ref.injector.get(HttpClient); ref.injector.get(NgZone).run(() => { - http.get('http://localhost/testing').subscribe((body: string) => { + http.get('http://localhost/testing').subscribe((body: string) => { NgZone.assertInAngularZone(); expect(body).toEqual('success!'); }); @@ -791,8 +791,8 @@ class HiddenModule { platform.bootstrapModule(HttpClientExampleModule).then(ref => { const mock = ref.injector.get(HttpTestingController) as HttpTestingController; const http = ref.injector.get(HttpClient); - ref.injector.get(NgZone).run(() => { - http.get('http://localhost/testing').subscribe((body: string) => { + ref.injector.get(NgZone).run(() => { + http.get('http://localhost/testing').subscribe((body: string) => { expect(body).toEqual('success!'); }); expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy(); @@ -808,8 +808,8 @@ class HiddenModule { platform.bootstrapModule(HttpInterceptorExampleModule).then(ref => { const mock = ref.injector.get(HttpTestingController) as HttpTestingController; const http = ref.injector.get(HttpClient); - ref.injector.get(NgZone).run(() => { - http.get('http://localhost/testing').subscribe((body: string) => { + ref.injector.get(NgZone).run(() => { + http.get('http://localhost/testing').subscribe((body: string) => { NgZone.assertInAngularZone(); expect(body).toEqual('success!'); }); diff --git a/tools/public_api_guard/core/core.d.ts b/tools/public_api_guard/core/core.d.ts index a552de6b55..c701470f6f 100644 --- a/tools/public_api_guard/core/core.d.ts +++ b/tools/public_api_guard/core/core.d.ts @@ -456,7 +456,7 @@ export declare class InjectionToken { } export declare abstract class Injector { - abstract get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): T; + abstract get(token: Type | InjectionToken | AbstractType, notFoundValue?: T, flags?: InjectFlags): T; /** @deprecated */ abstract get(token: any, notFoundValue?: any): any; static NULL: Injector; static THROW_IF_NOT_FOUND: Object; diff --git a/tools/public_api_guard/core/testing.d.ts b/tools/public_api_guard/core/testing.d.ts index 49da6241dc..ffc1679f14 100644 --- a/tools/public_api_guard/core/testing.d.ts +++ b/tools/public_api_guard/core/testing.d.ts @@ -58,9 +58,11 @@ export interface TestBed { configureTestingModule(moduleDef: TestModuleMetadata): void; createComponent(component: Type): ComponentFixture; execute(tokens: any[], fn: Function, context?: any): any; - get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; get(token: any, notFoundValue?: any): any; + get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; initTestEnvironment(ngModule: Type | Type[], platform: PlatformRef, aotSummaries?: () => any[]): void; + inject(token: Type | InjectionToken | AbstractType, notFoundValue?: T, flags?: InjectFlags): T; + inject(token: Type | InjectionToken | AbstractType, notFoundValue: null, flags?: InjectFlags): T | null; overrideComponent(component: Type, override: MetadataOverride): void; overrideDirective(directive: Type, override: MetadataOverride): void; overrideModule(ngModule: Type, override: MetadataOverride): void; @@ -93,17 +95,15 @@ export interface TestBedStatic { }): TestBedStatic; configureTestingModule(moduleDef: TestModuleMetadata): TestBedStatic; createComponent(component: Type): ComponentFixture; - get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; get(token: any, notFoundValue?: any): any; + get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; initTestEnvironment(ngModule: Type | Type[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed; + inject(token: Type | InjectionToken | AbstractType, notFoundValue: null, flags?: InjectFlags): T | null; + inject(token: Type | InjectionToken | AbstractType, notFoundValue?: T, flags?: InjectFlags): T; overrideComponent(component: Type, override: MetadataOverride): TestBedStatic; overrideDirective(directive: Type, override: MetadataOverride): TestBedStatic; overrideModule(ngModule: Type, override: MetadataOverride): TestBedStatic; overridePipe(pipe: Type, override: MetadataOverride): TestBedStatic; - overrideProvider(token: any, provider: { - useFactory: Function; - deps: any[]; - }): TestBedStatic; overrideProvider(token: any, provider: { useValue: any; }): TestBedStatic; @@ -112,6 +112,10 @@ export interface TestBedStatic { useValue?: any; deps?: any[]; }): TestBedStatic; + overrideProvider(token: any, provider: { + useFactory: Function; + deps: any[]; + }): TestBedStatic; overrideTemplate(component: Type, template: string): TestBedStatic; overrideTemplateUsingTestingModule(component: Type, template: string): TestBedStatic; resetTestEnvironment(): void;