test(docs-infra): remove deprecated `ReflectiveInjector` (#38408)

This commit replaces the old and slow `ReflectiveInjector` that was
deprecated in v5 with the new `Injector`. Note: This change was only
done in the spec files inside the `aio` folder.

While changing this, it was not possible to directly use `Injector.get`
to get the correct typing for the mocked classes. For example:

```typescript
locationService = injector.get<TestLocationService>(LocationService);
```

Fails with:

> Argument of type 'typeof LocationService' is not assignable to parameter
of type 'Type<TestLocationService> | InjectionToken<TestLocationService> |
AbstractType<TestLocationService>'.
  Type 'typeof LocationService' is not assignable to type 'Type<TestLocationService>'.
    Property 'searchResult' is missing in type 'LocationService' but required in type
    'TestLocationService'.

Therefore, it was necessary to first convert to `unknown` and then to
`TestLocationService`.

```typescript
locationService = injector.get(LocationService) as unknown as TestLocationService;
```

PR Close #38408
This commit is contained in:
Sonu Kapoor 2020-08-10 19:02:47 -04:00 committed by Andrew Scott
parent 945751e2e8
commit 175c79d1d8
12 changed files with 118 additions and 98 deletions

View File

@ -1,4 +1,4 @@
import { ReflectiveInjector } from '@angular/core';
import { Injector } from '@angular/core';
import { of } from 'rxjs';
@ -12,20 +12,22 @@ import { LocationService } from 'app/shared/location.service';
describe('ContributorListComponent', () => {
let component: ContributorListComponent;
let injector: ReflectiveInjector;
let injector: Injector;
let contributorService: TestContributorService;
let locationService: TestLocationService;
let contributorGroups: ContributorGroup[];
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
ContributorListComponent,
{provide: ContributorService, useClass: TestContributorService },
{provide: LocationService, useClass: TestLocationService }
]);
injector = Injector.create({
providers: [
{provide: ContributorListComponent, deps: [ContributorService, LocationService] },
{provide: ContributorService, useClass: TestContributorService, deps: [] },
{provide: LocationService, useClass: TestLocationService, deps: [] }
]
});
locationService = injector.get(LocationService);
contributorService = injector.get(ContributorService);
locationService = injector.get(LocationService) as unknown as TestLocationService;
contributorService = injector.get(ContributorService) as unknown as TestContributorService;
contributorGroups = contributorService.testContributors;
});

View File

@ -1,4 +1,4 @@
import { ReflectiveInjector } from '@angular/core';
import { Injector } from '@angular/core';
import { of } from 'rxjs';
@ -12,20 +12,22 @@ import { Category } from './resource.model';
describe('ResourceListComponent', () => {
let component: ResourceListComponent;
let injector: ReflectiveInjector;
let injector: Injector;
let resourceService: TestResourceService;
let locationService: TestLocationService;
let categories: Category[];
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
ResourceListComponent,
{provide: ResourceService, useClass: TestResourceService },
{provide: LocationService, useClass: TestLocationService }
]);
injector = Injector.create({
providers: [
{provide: ResourceListComponent, deps: [ResourceService, LocationService] },
{provide: ResourceService, useClass: TestResourceService, deps: [] },
{provide: LocationService, useClass: TestLocationService, deps: [] }
]
});
locationService = injector.get(LocationService);
resourceService = injector.get(ResourceService);
locationService = injector.get(LocationService) as unknown as TestLocationService;
resourceService = injector.get(ResourceService) as unknown as TestResourceService;
categories = resourceService.testCategories;
});

View File

@ -1,4 +1,4 @@
import { ReflectiveInjector, NgZone } from '@angular/core';
import { Injector, NgZone } from '@angular/core';
import { fakeAsync, tick } from '@angular/core/testing';
import { of } from 'rxjs';
import { SearchService } from './search.service';
@ -6,7 +6,7 @@ import { WebWorkerClient } from 'app/shared/web-worker';
describe('SearchService', () => {
let injector: ReflectiveInjector;
let injector: Injector;
let service: SearchService;
let sendMessageSpy: jasmine.Spy;
let mockWorker: WebWorkerClient;
@ -16,10 +16,13 @@ describe('SearchService', () => {
mockWorker = { sendMessage: sendMessageSpy } as any;
spyOn(WebWorkerClient, 'create').and.returnValue(mockWorker);
injector = ReflectiveInjector.resolveAndCreate([
SearchService,
{ provide: NgZone, useFactory: () => new NgZone({ enableLongStackTrace: false }) }
]);
injector = Injector.create({
providers: [
{ provide: SearchService, deps: [NgZone]},
{ provide: NgZone, useFactory: () => new NgZone({ enableLongStackTrace: false }), deps: [] }
]
});
service = injector.get(SearchService);
});

View File

@ -1,4 +1,4 @@
import { ReflectiveInjector } from '@angular/core';
import { Injector } from '@angular/core';
import { environment } from 'environments/environment';
import { LocationService } from 'app/shared/location.service';
import { MockLocationService } from 'testing/location.service';
@ -15,7 +15,7 @@ describe('Deployment service', () => {
it('should get the mode from the `mode` query parameter if available', () => {
const injector = getInjector();
const locationService: MockLocationService = injector.get(LocationService);
const locationService = injector.get(LocationService) as unknown as MockLocationService;
locationService.search.and.returnValue({ mode: 'bar' });
const deployment = injector.get(Deployment);
@ -25,8 +25,8 @@ describe('Deployment service', () => {
});
function getInjector() {
return ReflectiveInjector.resolveAndCreate([
Deployment,
{ provide: LocationService, useFactory: () => new MockLocationService('') }
]);
return Injector.create({providers: [
{ provide: Deployment, deps: [LocationService] },
{ provide: LocationService, useFactory: () => new MockLocationService(''), deps: [] }
]});
}

View File

@ -1,18 +1,23 @@
import { ReflectiveInjector } from '@angular/core';
import { Injector } from '@angular/core';
import { GaService } from 'app/shared/ga.service';
import { WindowToken } from 'app/shared/window';
describe('GaService', () => {
let gaService: GaService;
let injector: ReflectiveInjector;
let injector: Injector;
let gaSpy: jasmine.Spy;
let mockWindow: any;
beforeEach(() => {
gaSpy = jasmine.createSpy('ga');
mockWindow = { ga: gaSpy };
injector = ReflectiveInjector.resolveAndCreate([GaService, { provide: WindowToken, useFactory: () => mockWindow }]);
injector = Injector.create({
providers: [
{ provide: GaService, deps: [WindowToken] },
{ provide: WindowToken, useFactory: () => mockWindow, deps: [] }
]});
gaService = injector.get(GaService);
});

View File

@ -1,4 +1,4 @@
import { ReflectiveInjector } from '@angular/core';
import { Injector } from '@angular/core';
import { Location, LocationStrategy, PlatformLocation } from '@angular/common';
import { MockLocationStrategy } from '@angular/common/testing';
import { Subject } from 'rxjs';
@ -9,26 +9,28 @@ import { LocationService } from './location.service';
import { ScrollService } from './scroll.service';
describe('LocationService', () => {
let injector: ReflectiveInjector;
let injector: Injector;
let location: MockLocationStrategy;
let service: LocationService;
let swUpdates: MockSwUpdatesService;
let scrollService: MockScrollService;
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
LocationService,
Location,
{ provide: GaService, useClass: TestGaService },
{ provide: LocationStrategy, useClass: MockLocationStrategy },
{ provide: PlatformLocation, useClass: MockPlatformLocation },
{ provide: SwUpdatesService, useClass: MockSwUpdatesService },
{ provide: ScrollService, useClass: MockScrollService }
]);
injector = Injector.create({
providers: [
{ provide: LocationService, deps: [GaService, Location, ScrollService, PlatformLocation, SwUpdatesService] },
{ provide: Location, deps: [LocationStrategy, PlatformLocation] },
{ provide: GaService, useClass: TestGaService, deps: [] },
{ provide: LocationStrategy, useClass: MockLocationStrategy, deps: [] },
{ provide: PlatformLocation, useClass: MockPlatformLocation, deps: [] },
{ provide: SwUpdatesService, useClass: MockSwUpdatesService, deps: [] },
{ provide: ScrollService, useClass: MockScrollService, deps: [] }
]
});
location = injector.get(LocationStrategy);
location = injector.get(LocationStrategy) as unknown as MockLocationStrategy;
service = injector.get(LocationService);
swUpdates = injector.get(SwUpdatesService);
swUpdates = injector.get(SwUpdatesService) as unknown as MockSwUpdatesService;
scrollService = injector.get(ScrollService);
});
@ -380,7 +382,7 @@ describe('LocationService', () => {
let platformLocation: MockPlatformLocation;
beforeEach(() => {
platformLocation = injector.get(PlatformLocation);
platformLocation = injector.get(PlatformLocation) as unknown as MockPlatformLocation;
});
it('should call replaceState on PlatformLocation', () => {
@ -577,7 +579,7 @@ describe('LocationService', () => {
let gaLocationChanged: jasmine.Spy;
beforeEach(() => {
const gaService = injector.get(GaService);
const gaService = injector.get(GaService) as unknown as TestGaService;
gaLocationChanged = gaService.locationChanged;
// execute currentPath observable so that gaLocationChanged is called
service.currentPath.subscribe();

View File

@ -1,4 +1,4 @@
import { ErrorHandler, ReflectiveInjector } from '@angular/core';
import { ErrorHandler, Injector } from '@angular/core';
import { Logger } from './logger.service';
describe('logger service', () => {
@ -10,10 +10,10 @@ describe('logger service', () => {
beforeEach(() => {
logSpy = spyOn(console, 'log');
warnSpy = spyOn(console, 'warn');
const injector = ReflectiveInjector.resolveAndCreate([
Logger,
{ provide: ErrorHandler, useClass: MockErrorHandler }
]);
const injector = Injector.create({providers: [
{ provide: Logger, deps: [ErrorHandler] },
{ provide: ErrorHandler, useClass: MockErrorHandler, deps: [] }
]});
logger = injector.get(Logger);
errorHandler = injector.get(ErrorHandler);
});

View File

@ -1,4 +1,4 @@
import { ErrorHandler, ReflectiveInjector } from '@angular/core';
import { ErrorHandler, Injector } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { WindowToken } from 'app/shared/window';
import { AppModule } from 'app/app.module';
@ -14,11 +14,12 @@ describe('ReportingErrorHandler service', () => {
onerrorSpy = jasmine.createSpy('onerror');
superHandler = spyOn(ErrorHandler.prototype, 'handleError');
const injector = ReflectiveInjector.resolveAndCreate([
{ provide: ErrorHandler, useClass: ReportingErrorHandler },
{ provide: WindowToken, useFactory: () => ({ onerror: onerrorSpy }) }
]);
handler = injector.get(ErrorHandler);
const injector = Injector.create({providers: [
{ provide: ErrorHandler, useClass: ReportingErrorHandler, deps: [WindowToken] },
{ provide: WindowToken, useFactory: () => ({ onerror: onerrorSpy }), deps: [] }
]});
handler = injector.get(ErrorHandler) as unknown as ReportingErrorHandler;
});
it('should be registered on the AppModule', () => {

View File

@ -1,4 +1,4 @@
import { Injector, ReflectiveInjector } from '@angular/core';
import { Injector } from '@angular/core';
import { fakeAsync, tick } from '@angular/core/testing';
import { DOCUMENT } from '@angular/common';
@ -151,11 +151,11 @@ describe('ScrollSpyService', () => {
let scrollSpyService: ScrollSpyService;
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
injector = Injector.create({providers: [
{ provide: DOCUMENT, useValue: { body: {} } },
{ provide: ScrollService, useValue: { topOffset: 50 } },
ScrollSpyService
]);
{ provide: ScrollSpyService, deps: [DOCUMENT, ScrollService] }
]});
scrollSpyService = injector.get(ScrollSpyService);
});

View File

@ -1,7 +1,7 @@
import {Location, LocationStrategy, PlatformLocation, ViewportScroller} from '@angular/common';
import {DOCUMENT} from '@angular/common';
import {MockLocationStrategy, SpyLocation} from '@angular/common/testing';
import {ReflectiveInjector} from '@angular/core';
import {Injector} from '@angular/core';
import {fakeAsync, tick} from '@angular/core/testing';
import {ScrollService, topMargin} from './scroll.service';
@ -15,7 +15,7 @@ describe('ScrollService', () => {
};
const topOfPageElem = {} as Element;
let injector: ReflectiveInjector;
let injector: Injector;
let document: MockDocument;
let platformLocation: MockPlatformLocation;
let scrollService: ScrollService;
@ -41,21 +41,25 @@ describe('ScrollService', () => {
jasmine.createSpyObj('viewportScroller', ['getScrollPosition', 'scrollToPosition']);
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
injector = Injector.create( {
providers: [
{
provide: ScrollService,
useFactory: createScrollService,
deps: [DOCUMENT, PlatformLocation, ViewportScroller, Location],
},
{provide: Location, useClass: SpyLocation}, {provide: DOCUMENT, useClass: MockDocument},
{provide: PlatformLocation, useClass: MockPlatformLocation},
{provide: Location, useClass: SpyLocation, deps: [] },
{provide: DOCUMENT, useClass: MockDocument, deps: []},
{provide: PlatformLocation, useClass: MockPlatformLocation, deps: []},
{provide: ViewportScroller, useValue: viewportScrollerStub},
{provide: LocationStrategy, useClass: MockLocationStrategy}
]);
{provide: LocationStrategy, useClass: MockLocationStrategy, deps: []}
]
});
platformLocation = injector.get(PlatformLocation);
document = injector.get(DOCUMENT);
document = injector.get(DOCUMENT) as unknown as MockDocument;
scrollService = injector.get(ScrollService);
location = injector.get(Location);
location = injector.get(Location) as unknown as SpyLocation;
spyOn(window, 'scrollBy');
});

View File

@ -1,5 +1,5 @@
import { DOCUMENT } from '@angular/common';
import { ReflectiveInjector } from '@angular/core';
import { Injector } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Subject } from 'rxjs';
@ -7,7 +7,7 @@ import { ScrollItem, ScrollSpyInfo, ScrollSpyService } from 'app/shared/scroll-s
import { TocItem, TocService } from './toc.service';
describe('TocService', () => {
let injector: ReflectiveInjector;
let injector: Injector;
let scrollSpyService: MockScrollSpyService;
let tocService: TocService;
let lastTocList: TocItem[];
@ -21,13 +21,14 @@ describe('TocService', () => {
}
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
{ provide: DomSanitizer, useClass: TestDomSanitizer },
injector = Injector.create({providers: [
{ provide: DomSanitizer, useClass: TestDomSanitizer, deps: [] },
{ provide: DOCUMENT, useValue: document },
{ provide: ScrollSpyService, useClass: MockScrollSpyService },
TocService,
]);
scrollSpyService = injector.get(ScrollSpyService);
{ provide: ScrollSpyService, useClass: MockScrollSpyService, deps: [] },
{ provide: TocService, deps: [DOCUMENT, DomSanitizer, ScrollSpyService] },
]});
scrollSpyService = injector.get(ScrollSpyService) as unknown as MockScrollSpyService;
tocService = injector.get(TocService);
tocService.tocList.subscribe(tocList => lastTocList = tocList);
});
@ -330,7 +331,7 @@ describe('TocService', () => {
});
it('should have bypassed HTML sanitizing of heading\'s innerHTML ', () => {
const domSanitizer: TestDomSanitizer = injector.get(DomSanitizer);
const domSanitizer: TestDomSanitizer = injector.get(DomSanitizer) as unknown as TestDomSanitizer;
expect(domSanitizer.bypassSecurityTrustHtml)
.toHaveBeenCalledWith('Setup to develop <i>locally</i>.');
});

View File

@ -1,4 +1,4 @@
import { ApplicationRef, ReflectiveInjector } from '@angular/core';
import { ApplicationRef, Injector } from '@angular/core';
import { discardPeriodicTasks, fakeAsync, tick } from '@angular/core/testing';
import { SwUpdate } from '@angular/service-worker';
import { Subject } from 'rxjs';
@ -8,7 +8,7 @@ import { SwUpdatesService } from './sw-updates.service';
describe('SwUpdatesService', () => {
let injector: ReflectiveInjector;
let injector: Injector;
let appRef: MockApplicationRef;
let service: SwUpdatesService;
let swu: MockSwUpdate;
@ -21,16 +21,16 @@ describe('SwUpdatesService', () => {
// run `setup()`/`tearDown()` in `beforeEach()`/`afterEach()` blocks. We use the `run()` helper
// to call them inside each test's zone.
const setup = (isSwUpdateEnabled: boolean) => {
injector = ReflectiveInjector.resolveAndCreate([
{ provide: ApplicationRef, useClass: MockApplicationRef },
{ provide: Logger, useClass: MockLogger },
{ provide: SwUpdate, useFactory: () => new MockSwUpdate(isSwUpdateEnabled) },
SwUpdatesService
]);
injector = Injector.create({providers: [
{ provide: ApplicationRef, useClass: MockApplicationRef, deps: [] },
{ provide: Logger, useClass: MockLogger, deps: [] },
{ provide: SwUpdate, useFactory: () => new MockSwUpdate(isSwUpdateEnabled), deps: [] },
{ provide: SwUpdatesService, deps: [ApplicationRef, Logger, SwUpdate] }
]});
appRef = injector.get(ApplicationRef);
appRef = injector.get(ApplicationRef) as unknown as MockApplicationRef;
service = injector.get(SwUpdatesService);
swu = injector.get(SwUpdate);
swu = injector.get(SwUpdate) as unknown as MockSwUpdate;
checkInterval = (service as any).checkInterval;
};
const tearDown = () => service.ngOnDestroy();