Skip to content

Commit

Permalink
refactor(core): Migrate TestBed.get to TestBed.inject (#32382)
Browse files Browse the repository at this point in the history
This is cleanup/followup for PR #32200

PR Close #32382
  • Loading branch information
Goodwine authored and matsko committed Sep 9, 2019
1 parent a64eded commit 9166baf
Show file tree
Hide file tree
Showing 69 changed files with 507 additions and 485 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ describe('HeroesService', () => {

// Inject the http, test controller, and service-under-test
// as they will be referenced by each test.
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
heroService = TestBed.get(HeroesService);
httpClient = TestBed.inject(HttpClient);
httpTestingController = TestBed.inject(HttpTestingController);
heroService = TestBed.inject(HeroesService);
});

afterEach(() => {
Expand All @@ -44,7 +44,7 @@ describe('HeroesService', () => {
let expectedHeroes: Hero[];

beforeEach(() => {
heroService = TestBed.get(HeroesService);
heroService = TestBed.inject(HeroesService);
expectedHeroes = [
{ id: 1, name: 'A' },
{ id: 2, name: 'B' },
Expand Down
4 changes: 2 additions & 2 deletions aio/content/examples/http/src/testing/http-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ describe('HttpClient testing', () => {
});

// Inject the http service and test controller for each test
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
httpClient = TestBed.inject(HttpClient);
httpTestingController = TestBed.inject(HttpTestingController);
});
// #enddocregion setup
// #docregion afterEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('MyLibService', () => {
beforeEach(() => TestBed.configureTestingModule({}));

it('should be created', () => {
const service: MyLibService = TestBed.get(MyLibService);
const service: MyLibService = TestBed.inject(MyLibService);
expect(service).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ xdescribe('AppComponent & Lazy Loading (not working yet)', () => {

beforeEach(fakeAsync(() => {
createComponent();
loader = TestBed.get(NgModuleFactoryLoader);
loader = TestBed.inject(NgModuleFactoryLoader);
loader.stubbedModules = { expected: HeroModule };
router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]);
}));
Expand Down
10 changes: 5 additions & 5 deletions aio/content/examples/testing/src/app/demo/demo.testbed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,21 @@ describe('demo (with TestBed):', () => {
beforeEach(() => {
TestBed.configureTestingModule({ providers: [ValueService] });
// #enddocregion value-service-before-each
service = TestBed.get(ValueService);
service = TestBed.inject(ValueService);
// #docregion value-service-before-each
});
// #enddocregion value-service-before-each, value-service-inject-before-each

// #docregion value-service-inject-it
it('should use ValueService', () => {
service = TestBed.get(ValueService);
service = TestBed.inject(ValueService);
expect(service.getValue()).toBe('real value');
});
// #enddocregion value-service-inject-it

it('can inject a default value when service is not provided', () => {
// #docregion testbed-get-w-null
service = TestBed.get(NotProvided, null); // service is null
service = TestBed.inject(NotProvided, null); // service is null
// #enddocregion testbed-get-w-null
});

Expand Down Expand Up @@ -109,8 +109,8 @@ describe('demo (with TestBed):', () => {
]
});
// Inject both the service-to-test and its (spy) dependency
masterService = TestBed.get(MasterService);
valueServiceSpy = TestBed.get(ValueService);
masterService = TestBed.inject(MasterService);
valueServiceSpy = TestBed.inject(ValueService);
});
// #enddocregion master-service-before-each

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ describe('HeroesService (with mocks)', () => {

// Inject the http, test controller, and service-under-test
// as they will be referenced by each test.
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
heroService = TestBed.get(HeroService);
httpClient = TestBed.inject(HttpClient);
httpTestingController = TestBed.inject(HttpTestingController);
heroService = TestBed.inject(HeroService);
});

afterEach(() => {
Expand All @@ -80,7 +80,7 @@ describe('HeroesService (with mocks)', () => {
let expectedHeroes: Hero[];

beforeEach(() => {
heroService = TestBed.get(HeroService);
heroService = TestBed.inject(HeroService);
expectedHeroes = [
{ id: 1, name: 'A' },
{ id: 2, name: 'B' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ describe('HttpClient testing', () => {
});

// Inject the http service and test controller for each test
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
httpClient = TestBed.inject(HttpClient);
httpTestingController = TestBed.inject(HttpTestingController);
});
// #enddocregion setup
// #docregion afterEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ describe('WelcomeComponent (class only)', () => {
]
});
// inject both the component and the dependent service.
comp = TestBed.get(WelcomeComponent);
userService = TestBed.get(UserService);
comp = TestBed.inject(WelcomeComponent);
userService = TestBed.inject(UserService);
});
// #enddocregion class-only-before-each

Expand Down Expand Up @@ -93,7 +93,7 @@ describe('WelcomeComponent', () => {
// #docregion setup
// #docregion inject-from-testbed
// UserService from the root injector
userService = TestBed.get(UserService);
userService = TestBed.inject(UserService);
// #enddocregion inject-from-testbed

// get the "welcome" element by CSS selector (e.g., by class name)
Expand Down
2 changes: 1 addition & 1 deletion aio/content/guide/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ the setup of the _service-under-test_.
Now requests made in the course of your tests will hit the testing backend instead of the normal backend.
This setup also calls `TestBed.get()` to inject the `HttpClient` service and the mocking controller
This setup also calls `TestBed.inject()` to inject the `HttpClient` service and the mocking controller
so they can be referenced during the tests.
### Expecting and answering requests
Expand Down
21 changes: 13 additions & 8 deletions aio/content/guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,12 @@ array of the services that you'll test or mock.
header="app/demo/demo.testbed.spec.ts (provide ValueService in beforeEach">
</code-example>

Then inject it inside a test by calling `TestBed.get()` with the service class as the argument.
Then inject it inside a test by calling `TestBed.inject()` with the service class as the argument.

**Note:** We used to have `TestBed.get()` instead of `TestBed.inject()`.
The `get` method wasn't type safe, it always returned `any`, and this is error prone.
We decided to migrate to a new function instead of updating the existing one given
the large scale use that would have an immense amount of breaking changes.

<code-example
path="testing/src/app/demo/demo.testbed.spec.ts"
Expand Down Expand Up @@ -1063,14 +1068,14 @@ The component injector is a property of the fixture's `DebugElement`.

{@a testbed-get}

#### _TestBed.get()_
#### _TestBed.inject()_

You _may_ also be able to get the service from the root injector via `TestBed.get()`.
You _may_ also be able to get the service from the root injector via `TestBed.inject()`.
This is easier to remember and less verbose.
But it only works when Angular injects the component with the service instance in the test's root injector.

In this test suite, the _only_ provider of `UserService` is the root testing module,
so it is safe to call `TestBed.get()` as follows:
so it is safe to call `TestBed.inject()` as follows:

<code-example
path="testing/src/app/welcome/welcome.component.spec.ts"
Expand All @@ -1080,7 +1085,7 @@ so it is safe to call `TestBed.get()` as follows:

<div class="alert is-helpful">

For a use case in which `TestBed.get()` does not work,
For a use case in which `TestBed.inject()` does not work,
see the [_Override component providers_](#component-override) section that
explains when and why you must get the service from the component's injector instead.

Expand All @@ -1102,7 +1107,7 @@ a clone of the provided `userServiceStub`.

#### Final setup and tests

Here's the complete `beforeEach()`, using `TestBed.get()`:
Here's the complete `beforeEach()`, using `TestBed.inject()`:

<code-example path="testing/src/app/welcome/welcome.component.spec.ts" region="setup" header="app/welcome/welcome.component.spec.ts"></code-example>

Expand Down Expand Up @@ -3090,13 +3095,13 @@ Here are the most important static methods, in order of likely utility.

What if the service is optional?

The `TestBed.get()` method takes an optional second parameter,
The `TestBed.inject()` method takes an optional second parameter,
the object to return if Angular can't find the provider
(`null` in this example):

<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="testbed-get-w-null" header="app/demo/demo.testbed.spec.ts"></code-example>

After calling `get`, the `TestBed` configuration is frozen for the duration of the current spec.
After calling `TestBed.inject`, the `TestBed` configuration is frozen for the duration of the current spec.

</td>
</tr>
Expand Down
24 changes: 12 additions & 12 deletions aio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,17 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^8.1.0-next.1",
"@angular/animations": "^9.0.0-next.5",
"@angular/cdk": "8.0.0",
"@angular/common": "^8.1.0-next.1",
"@angular/core": "^8.1.0-next.1",
"@angular/elements": "^8.1.0-next.1",
"@angular/forms": "^8.1.0-next.1",
"@angular/common": "^9.0.0-next.5",
"@angular/core": "^9.0.0-next.5",
"@angular/elements": "^9.0.0-next.5",
"@angular/forms": "^9.0.0-next.5",
"@angular/material": "8.0.0",
"@angular/platform-browser": "^8.1.0-next.1",
"@angular/platform-browser-dynamic": "^8.1.0-next.1",
"@angular/router": "^8.1.0-next.1",
"@angular/service-worker": "^8.1.0-next.1",
"@angular/platform-browser": "^9.0.0-next.5",
"@angular/platform-browser-dynamic": "^9.0.0-next.5",
"@angular/router": "^9.0.0-next.5",
"@angular/service-worker": "^9.0.0-next.5",
"@types/lunr": "^2.3.2",
"@webcomponents/custom-elements": "^1.2.0",
"rxjs": "^6.5.2",
Expand All @@ -103,9 +103,9 @@
"devDependencies": {
"@angular-devkit/build-angular": "0.801.0-beta.2",
"@angular/cli": "8.1.0-beta.2",
"@angular/compiler": "^8.1.0-next.1",
"@angular/compiler-cli": "^8.1.0-next.1",
"@angular/language-service": "^8.1.0-next.1",
"@angular/compiler": "^9.0.0-next.5",
"@angular/compiler-cli": "^9.0.0-next.5",
"@angular/language-service": "^9.0.0-next.5",
"@types/jasmine": "^2.5.52",
"@types/jasminewd2": "^2.0.4",
"@types/node": "~6.0.60",
Expand Down
4 changes: 2 additions & 2 deletions aio/scripts/_payload-limits.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"uncompressed": {
"runtime-es5": 3042,
"runtime-es2015": 3048,
"main-es5": 511052,
"main-es2015": 450562,
"main-es5": 493318,
"main-es2015": 434710,
"polyfills-es5": 131024,
"polyfills-es2015": 52433
}
Expand Down
14 changes: 7 additions & 7 deletions aio/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,15 +442,15 @@ describe('AppComponent', () => {
});

it('should update the document title', async () => {
const titleService = TestBed.get(Title);
const titleService = TestBed.inject(Title);
spyOn(titleService, 'setTitle');

await navigateTo('guide/pipes');
expect(titleService.setTitle).toHaveBeenCalledWith('Angular - Pipes');
});

it('should update the document title, with a default value if the document has no title', async () => {
const titleService = TestBed.get(Title);
const titleService = TestBed.inject(Title);
spyOn(titleService, 'setTitle');

await navigateTo('no-title');
Expand Down Expand Up @@ -782,14 +782,14 @@ describe('AppComponent', () => {

describe('showing search results', () => {
it('should not display search results when query is empty', () => {
const searchService: MockSearchService = TestBed.get(SearchService);
const searchService = TestBed.inject(SearchService) as Partial<SearchService> as MockSearchService;
searchService.searchResults.next({ query: '', results: [] });
fixture.detectChanges();
expect(component.showSearchResults).toBe(false);
});

it('should hide the results when a search result is selected', () => {
const searchService: MockSearchService = TestBed.get(SearchService);
const searchService = TestBed.inject(SearchService) as Partial<SearchService> as MockSearchService;

const results = [
{ path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false }
Expand Down Expand Up @@ -826,14 +826,14 @@ describe('AppComponent', () => {
const description =
`should ${doRedirect ? '' : 'not '}redirect to 'docs' if deployment mode is '${mode}' ` +
'and at a marketing page';
const verifyNoRedirection = () => expect(TestBed.get(LocationService).replace).not.toHaveBeenCalled();
const verifyRedirection = () => expect(TestBed.get(LocationService).replace).toHaveBeenCalledWith('docs');
const verifyNoRedirection = () => expect(TestBed.inject(LocationService).replace).not.toHaveBeenCalled();
const verifyRedirection = () => expect(TestBed.inject(LocationService).replace).toHaveBeenCalledWith('docs');
const verifyPossibleRedirection = doRedirect ? verifyRedirection : verifyNoRedirection;

it(description, () => {
createTestingModule('', mode);

const navService = TestBed.get(NavigationService) as NavigationService;
const navService = TestBed.inject(NavigationService);
const testCurrentNodes = navService.currentNodes = new Subject<CurrentNodes>();

initializeTest(false);
Expand Down
16 changes: 8 additions & 8 deletions aio/src/app/custom-elements/code/code.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,22 +222,22 @@ describe('CodeComponent', () => {
});

it('should call copier service when clicked', () => {
const copierService: CopierService = TestBed.get(CopierService);
const copierService: CopierService = TestBed.inject(CopierService);
const spy = spyOn(copierService, 'copyText');
expect(spy.calls.count()).toBe(0, 'before click');
getButton().click();
expect(spy.calls.count()).toBe(1, 'after click');
});

it('should copy code text when clicked', () => {
const copierService: CopierService = TestBed.get(CopierService);
const copierService: CopierService = TestBed.inject(CopierService);
const spy = spyOn(copierService, 'copyText');
getButton().click();
expect(spy.calls.argsFor(0)[0]).toBe(oneLineCode, 'after click');
});

it('should preserve newlines in the copied code', () => {
const copierService: CopierService = TestBed.get(CopierService);
const copierService: CopierService = TestBed.inject(CopierService);
const spy = spyOn(copierService, 'copyText');
const expectedCode = smallMultiLineCode.trim().replace(/&lt;/g, '<').replace(/&gt;/g, '>');
let actualCode;
Expand All @@ -258,18 +258,18 @@ describe('CodeComponent', () => {
});

it('should display a message when copy succeeds', () => {
const snackBar: MatSnackBar = TestBed.get(MatSnackBar);
const copierService: CopierService = TestBed.get(CopierService);
const snackBar: MatSnackBar = TestBed.inject(MatSnackBar);
const copierService: CopierService = TestBed.inject(CopierService);
spyOn(snackBar, 'open');
spyOn(copierService, 'copyText').and.returnValue(true);
getButton().click();
expect(snackBar.open).toHaveBeenCalledWith('Code Copied', '', { duration: 800 });
});

it('should display an error when copy fails', () => {
const snackBar: MatSnackBar = TestBed.get(MatSnackBar);
const copierService: CopierService = TestBed.get(CopierService);
const logger: TestLogger = TestBed.get(Logger);
const snackBar: MatSnackBar = TestBed.inject(MatSnackBar);
const copierService: CopierService = TestBed.inject(CopierService);
const logger = TestBed.inject(Logger) as unknown as TestLogger;
spyOn(snackBar, 'open');
spyOn(copierService, 'copyText').and.returnValue(false);
getButton().click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('FileNotFoundSearchComponent', () => {
});

fixture = TestBed.createComponent(FileNotFoundSearchComponent);
searchService = TestBed.get(SearchService);
searchService = TestBed.inject(SearchService);
searchResultSubject = new Subject<SearchResults>();
spyOn(searchService, 'search').and.callFake(() => searchResultSubject.asObservable());
fixture.detectChanges();
Expand Down

0 comments on commit 9166baf

Please sign in to comment.