Skip to content

Commit 7968402

Browse files
AndrewKushnirthePunderWoman
authored andcommitted
fix(core): align TestBed interfaces and implementation (#46635)
This commit performs various refactoring of the TestBed code to better align interfaces and implementation. The implementation class is also renamed from `TestBedRender3` -> `TestBedImpl`, but the public API name has not changed. Note: as a part of this change, the TestBed interface became more consistent and typings for multiple methods were updated to account for the fact that the TestBed reference is returned. This was always a runtime behavior of TestBed, which was not reflected in few places in type. PR Close #46635
1 parent 22c40b4 commit 7968402

File tree

7 files changed

+167
-299
lines changed

7 files changed

+167
-299
lines changed

goldens/public-api/core/testing/index.md

Lines changed: 16 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export function flush(maxTurns?: number): number;
6666
export function flushMicrotasks(): void;
6767

6868
// @public
69-
export const getTestBed: () => TestBed;
69+
export function getTestBed(): TestBed;
7070

7171
// @public
7272
export function inject(tokens: any[], fn: Function): () => any;
@@ -104,7 +104,7 @@ export interface TestBed {
104104
useJit?: boolean;
105105
}): void;
106106
// (undocumented)
107-
configureTestingModule(moduleDef: TestModuleMetadata): void;
107+
configureTestingModule(moduleDef: TestModuleMetadata): TestBed;
108108
// (undocumented)
109109
createComponent<T>(component: Type<T>): ComponentFixture<T>;
110110
// (undocumented)
@@ -119,90 +119,47 @@ export interface TestBed {
119119
// (undocumented)
120120
inject<T>(token: ProviderToken<T>, notFoundValue: null, flags?: InjectFlags): T | null;
121121
// (undocumented)
122-
ngModule: Type<any> | Type<any>[];
122+
get ngModule(): Type<any> | Type<any>[];
123123
// (undocumented)
124-
overrideComponent(component: Type<any>, override: MetadataOverride<Component>): void;
124+
overrideComponent(component: Type<any>, override: MetadataOverride<Component>): TestBed;
125125
// (undocumented)
126-
overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): void;
126+
overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): TestBed;
127127
// (undocumented)
128-
overrideModule(ngModule: Type<any>, override: MetadataOverride<NgModule>): void;
128+
overrideModule(ngModule: Type<any>, override: MetadataOverride<NgModule>): TestBed;
129129
// (undocumented)
130-
overridePipe(pipe: Type<any>, override: MetadataOverride<Pipe>): void;
130+
overridePipe(pipe: Type<any>, override: MetadataOverride<Pipe>): TestBed;
131131
overrideProvider(token: any, provider: {
132132
useFactory: Function;
133133
deps: any[];
134-
}): void;
134+
}): TestBed;
135135
// (undocumented)
136136
overrideProvider(token: any, provider: {
137137
useValue: any;
138-
}): void;
138+
}): TestBed;
139139
// (undocumented)
140140
overrideProvider(token: any, provider: {
141141
useFactory?: Function;
142142
useValue?: any;
143143
deps?: any[];
144-
}): void;
144+
}): TestBed;
145145
// (undocumented)
146-
overrideTemplateUsingTestingModule(component: Type<any>, template: string): void;
146+
overrideTemplate(component: Type<any>, template: string): TestBed;
147147
// (undocumented)
148-
platform: PlatformRef;
148+
overrideTemplateUsingTestingModule(component: Type<any>, template: string): TestBed;
149+
// (undocumented)
150+
get platform(): PlatformRef;
149151
resetTestEnvironment(): void;
150152
// (undocumented)
151-
resetTestingModule(): void;
153+
resetTestingModule(): TestBed;
152154
}
153155

154156
// @public
155157
export const TestBed: TestBedStatic;
156158

157159
// @public
158-
export interface TestBedStatic {
160+
export interface TestBedStatic extends TestBed {
159161
// (undocumented)
160162
new (...args: any[]): TestBed;
161-
compileComponents(): Promise<any>;
162-
configureCompiler(config: {
163-
providers?: any[];
164-
useJit?: boolean;
165-
}): TestBedStatic;
166-
configureTestingModule(moduleDef: TestModuleMetadata): TestBedStatic;
167-
// (undocumented)
168-
createComponent<T>(component: Type<T>): ComponentFixture<T>;
169-
// @deprecated (undocumented)
170-
get<T>(token: ProviderToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
171-
// @deprecated (undocumented)
172-
get(token: any, notFoundValue?: any): any;
173-
initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, options?: TestEnvironmentOptions): TestBed;
174-
// (undocumented)
175-
inject<T>(token: ProviderToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
176-
// (undocumented)
177-
inject<T>(token: ProviderToken<T>, notFoundValue: null, flags?: InjectFlags): T | null;
178-
// (undocumented)
179-
overrideComponent(component: Type<any>, override: MetadataOverride<Component>): TestBedStatic;
180-
// (undocumented)
181-
overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): TestBedStatic;
182-
// (undocumented)
183-
overrideModule(ngModule: Type<any>, override: MetadataOverride<NgModule>): TestBedStatic;
184-
// (undocumented)
185-
overridePipe(pipe: Type<any>, override: MetadataOverride<Pipe>): TestBedStatic;
186-
overrideProvider(token: any, provider: {
187-
useFactory: Function;
188-
deps: any[];
189-
}): TestBedStatic;
190-
// (undocumented)
191-
overrideProvider(token: any, provider: {
192-
useValue: any;
193-
}): TestBedStatic;
194-
// (undocumented)
195-
overrideProvider(token: any, provider: {
196-
useFactory?: Function;
197-
useValue?: any;
198-
deps?: any[];
199-
}): TestBedStatic;
200-
// (undocumented)
201-
overrideTemplate(component: Type<any>, template: string): TestBedStatic;
202-
overrideTemplateUsingTestingModule(component: Type<any>, template: string): TestBedStatic;
203-
resetTestEnvironment(): void;
204-
// (undocumented)
205-
resetTestingModule(): TestBedStatic;
206163
}
207164

208165
// @public

packages/core/test/test_bed_spec.ts

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {CommonModule} from '@angular/common';
109
import {APP_INITIALIZER, ChangeDetectorRef, Compiler, Component, Directive, ElementRef, ErrorHandler, getNgModuleById, Inject, Injectable, InjectionToken, Injector, Input, LOCALE_ID, ModuleWithProviders, NgModule, Optional, Pipe, Type, ViewChild, ɵsetClassMetadata as setClassMetadata, ɵɵdefineComponent as defineComponent, ɵɵdefineInjector as defineInjector, ɵɵdefineNgModule as defineNgModule, ɵɵelementEnd as elementEnd, ɵɵelementStart as elementStart, ɵɵsetNgModuleScope as setNgModuleScope, ɵɵtext as text} from '@angular/core';
11-
import {getTestBed, TestBed} from '@angular/core/testing/src/test_bed';
10+
import {TestBedImpl} from '@angular/core/testing/src/r3_test_bed';
11+
import {TestBed} from '@angular/core/testing/src/test_bed';
1212
import {By} from '@angular/platform-browser';
1313
import {expect} from '@angular/platform-browser/testing/src/matchers';
1414

15-
import {TestBedRender3} from '../testing/src/r3_test_bed';
1615
import {TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT, THROW_ON_UNKNOWN_ELEMENTS_DEFAULT, THROW_ON_UNKNOWN_PROPERTIES_DEFAULT} from '../testing/src/test_bed_common';
1716

1817
const NAME = new InjectionToken<string>('name');
@@ -129,7 +128,7 @@ describe('TestBed', () => {
129128
it('should apply scopes correctly for components in the lazy-loaded module', () => {
130129
// Reset TestBed to the initial state, emulating an invocation of a first test.
131130
// Check `TestBed.checkGlobalCompilationFinished` for additional info.
132-
(getTestBed() as any)._globalCompilationChecked = false;
131+
TestBedImpl.INSTANCE.globalCompilationChecked = false;
133132

134133
@Component({
135134
selector: 'root',
@@ -170,7 +169,7 @@ describe('TestBed', () => {
170169

171170
describe('TestBed with Standalone types', () => {
172171
beforeEach(() => {
173-
getTestBed().resetTestingModule();
172+
TestBed.resetTestingModule();
174173
});
175174

176175
it('should override providers on standalone component itself', () => {
@@ -498,7 +497,7 @@ describe('TestBed with Standalone types', () => {
498497

499498
describe('TestBed', () => {
500499
beforeEach(() => {
501-
getTestBed().resetTestingModule();
500+
TestBed.resetTestingModule();
502501
TestBed.configureTestingModule({imports: [HelloWorldModule]});
503502
});
504503

@@ -681,15 +680,15 @@ describe('TestBed', () => {
681680
expect(hello.nativeElement).toHaveText('Hello World!');
682681

683682
// override the template
684-
getTestBed().resetTestingModule();
683+
TestBed.resetTestingModule();
685684
TestBed.configureTestingModule({imports: [HelloWorldModule]});
686685
TestBed.overrideComponent(GreetingCmp, {set: {template: `Bonjour {{ name }}`}});
687686
hello = TestBed.createComponent(HelloWorld);
688687
hello.detectChanges();
689688
expect(hello.nativeElement).toHaveText('Bonjour World!');
690689

691690
// restore the original template by calling `.resetTestingModule()`
692-
getTestBed().resetTestingModule();
691+
TestBed.resetTestingModule();
693692
TestBed.configureTestingModule({imports: [HelloWorldModule]});
694693
hello = TestBed.createComponent(HelloWorld);
695694
hello.detectChanges();
@@ -1330,7 +1329,7 @@ describe('TestBed', () => {
13301329
class ProvidesErrorHandler {
13311330
}
13321331

1333-
getTestBed().resetTestingModule();
1332+
TestBed.resetTestingModule();
13341333
TestBed.configureTestingModule({imports: [ProvidesErrorHandler, HelloWorldModule]});
13351334

13361335
expect(TestBed.inject(ErrorHandler)).toEqual(jasmine.any(CustomErrorHandler));
@@ -1859,28 +1858,24 @@ describe('TestBed', () => {
18591858

18601859

18611860
describe('TestBed module teardown', () => {
1862-
// Cast the `TestBed` to the internal data type since we're testing private APIs.
1863-
let TestBed: TestBedRender3;
1864-
18651861
beforeEach(() => {
1866-
TestBed = getTestBed() as unknown as TestBedRender3;
18671862
TestBed.resetTestingModule();
18681863
});
18691864

18701865
it('should tear down the test module by default', () => {
1871-
expect(TestBed.shouldTearDownTestingModule()).toBe(true);
1866+
expect(TestBedImpl.INSTANCE.shouldTearDownTestingModule()).toBe(true);
18721867
});
18731868

18741869
it('should be able to configure the teardown behavior', () => {
18751870
TestBed.configureTestingModule({teardown: {destroyAfterEach: false}});
1876-
expect(TestBed.shouldTearDownTestingModule()).toBe(false);
1871+
expect(TestBedImpl.INSTANCE.shouldTearDownTestingModule()).toBe(false);
18771872
});
18781873

18791874
it('should reset the teardown behavior back to the default when TestBed is reset', () => {
18801875
TestBed.configureTestingModule({teardown: {destroyAfterEach: false}});
1881-
expect(TestBed.shouldTearDownTestingModule()).toBe(false);
1876+
expect(TestBedImpl.INSTANCE.shouldTearDownTestingModule()).toBe(false);
18821877
TestBed.resetTestingModule();
1883-
expect(TestBed.shouldTearDownTestingModule()).toBe(true);
1878+
expect(TestBedImpl.INSTANCE.shouldTearDownTestingModule()).toBe(true);
18841879
});
18851880

18861881
it('should destroy test module providers when test module teardown is enabled', () => {
@@ -2053,88 +2048,83 @@ describe('TestBed module teardown', () => {
20532048
});
20542049

20552050
it('should rethrow errors based on the default teardown behavior', () => {
2056-
expect(TestBed.shouldRethrowTeardownErrors()).toBe(TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT);
2051+
expect(TestBedImpl.INSTANCE.shouldRethrowTeardownErrors())
2052+
.toBe(TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT);
20572053
});
20582054

20592055
it('should rethrow errors if the option is omitted and test teardown is enabled', () => {
20602056
TestBed.configureTestingModule({teardown: {destroyAfterEach: true}});
2061-
expect(TestBed.shouldRethrowTeardownErrors()).toBe(true);
2057+
expect(TestBedImpl.INSTANCE.shouldRethrowTeardownErrors()).toBe(true);
20622058
});
20632059

20642060
it('should not rethrow errors if the option is omitted and test teardown is disabled', () => {
20652061
TestBed.configureTestingModule({teardown: {destroyAfterEach: false}});
2066-
expect(TestBed.shouldRethrowTeardownErrors()).toBe(false);
2062+
expect(TestBedImpl.INSTANCE.shouldRethrowTeardownErrors()).toBe(false);
20672063
});
20682064

20692065
it('should rethrow errors if the option is enabled, but teardown is disabled', () => {
20702066
TestBed.configureTestingModule({teardown: {destroyAfterEach: false, rethrowErrors: true}});
2071-
expect(TestBed.shouldRethrowTeardownErrors()).toBe(true);
2067+
expect(TestBedImpl.INSTANCE.shouldRethrowTeardownErrors()).toBe(true);
20722068
});
20732069

20742070
it('should not rethrow errors if the option is disabled, but teardown is enabled', () => {
20752071
TestBed.configureTestingModule({teardown: {destroyAfterEach: true, rethrowErrors: false}});
2076-
expect(TestBed.shouldRethrowTeardownErrors()).toBe(false);
2072+
expect(TestBedImpl.INSTANCE.shouldRethrowTeardownErrors()).toBe(false);
20772073
});
20782074
});
20792075

20802076
describe('TestBed module `errorOnUnknownElements`', () => {
2081-
// Cast the `TestBed` to the internal data type since we're testing private APIs.
2082-
let TestBed: TestBedRender3;
2083-
20842077
beforeEach(() => {
2085-
TestBed = getTestBed() as unknown as TestBedRender3;
20862078
TestBed.resetTestingModule();
20872079
});
20882080

20892081
it('should not throw based on the default behavior', () => {
2090-
expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(THROW_ON_UNKNOWN_ELEMENTS_DEFAULT);
2082+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownElements())
2083+
.toBe(THROW_ON_UNKNOWN_ELEMENTS_DEFAULT);
20912084
});
20922085

20932086
it('should not throw if the option is omitted', () => {
20942087
TestBed.configureTestingModule({});
2095-
expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(false);
2088+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownElements()).toBe(false);
20962089
});
20972090

20982091
it('should be able to configure the option', () => {
20992092
TestBed.configureTestingModule({errorOnUnknownElements: true});
2100-
expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(true);
2093+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownElements()).toBe(true);
21012094
});
21022095

21032096
it('should reset the option back to the default when TestBed is reset', () => {
21042097
TestBed.configureTestingModule({errorOnUnknownElements: true});
2105-
expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(true);
2098+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownElements()).toBe(true);
21062099
TestBed.resetTestingModule();
2107-
expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(false);
2100+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownElements()).toBe(false);
21082101
});
21092102
});
21102103

21112104
describe('TestBed module `errorOnUnknownProperties`', () => {
2112-
// Cast the `TestBed` to the internal data type since we're testing private APIs.
2113-
let TestBed: TestBedRender3;
2114-
21152105
beforeEach(() => {
2116-
TestBed = getTestBed() as unknown as TestBedRender3;
21172106
TestBed.resetTestingModule();
21182107
});
21192108

21202109
it('should not throw based on the default behavior', () => {
2121-
expect(TestBed.shouldThrowErrorOnUnknownProperties()).toBe(THROW_ON_UNKNOWN_PROPERTIES_DEFAULT);
2110+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownProperties())
2111+
.toBe(THROW_ON_UNKNOWN_PROPERTIES_DEFAULT);
21222112
});
21232113

21242114
it('should not throw if the option is omitted', () => {
21252115
TestBed.configureTestingModule({});
2126-
expect(TestBed.shouldThrowErrorOnUnknownProperties()).toBe(false);
2116+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownProperties()).toBe(false);
21272117
});
21282118

21292119
it('should be able to configure the option', () => {
21302120
TestBed.configureTestingModule({errorOnUnknownProperties: true});
2131-
expect(TestBed.shouldThrowErrorOnUnknownProperties()).toBe(true);
2121+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownProperties()).toBe(true);
21322122
});
21332123

21342124
it('should reset the option back to the default when TestBed is reset', () => {
21352125
TestBed.configureTestingModule({errorOnUnknownProperties: true});
2136-
expect(TestBed.shouldThrowErrorOnUnknownProperties()).toBe(true);
2126+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownProperties()).toBe(true);
21372127
TestBed.resetTestingModule();
2138-
expect(TestBed.shouldThrowErrorOnUnknownProperties()).toBe(false);
2128+
expect(TestBedImpl.INSTANCE.shouldThrowErrorOnUnknownProperties()).toBe(false);
21392129
});
21402130
});

0 commit comments

Comments
 (0)