feat(upgrade): provide unit test helpers for wiring up injectors (#16848)
Adds two new helper functions that can be used when unit testing Angular services that depend upon upgraded AngularJS services, or vice versa. The functions return a module (AngularJS or NgModule) that is configured to wire up the Angular and AngularJS injectors without the need to actually bootstrap a full hybrid application. This makes it simpler and faster to unit test services. PR Close #16848
This commit is contained in:

committed by
Kara Erickson

parent
5e53956c2b
commit
3fb78aaacc
@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injector, NgModule, Type} from '@angular/core';
|
||||
|
||||
import * as angular from '../../../src/common/src/angular1';
|
||||
import {$INJECTOR, INJECTOR_KEY, UPGRADE_APP_TYPE_KEY} from '../../../src/common/src/constants';
|
||||
import {UpgradeAppType} from '../../../src/common/src/util';
|
||||
|
||||
export let $injector: angular.IInjectorService|null = null;
|
||||
let injector: Injector;
|
||||
|
||||
export function $injectorFactory() {
|
||||
return $injector;
|
||||
}
|
||||
|
||||
@NgModule({providers: [{provide: $INJECTOR, useFactory: $injectorFactory}]})
|
||||
export class AngularTestingModule {
|
||||
constructor(i: Injector) { injector = i; }
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function to use when unit testing Angular services that depend upon upgraded AngularJS
|
||||
* services.
|
||||
*
|
||||
* This function returns an `NgModule` decorated class that is configured to wire up the Angular
|
||||
* and AngularJS injectors without the need to actually bootstrap a hybrid application.
|
||||
* This makes it simpler and faster to unit test services.
|
||||
*
|
||||
* Use the returned class as an "import" when configuring the `TestBed`.
|
||||
*
|
||||
* In the following code snippet, we are configuring the TestBed with two imports.
|
||||
* The `Ng2AppModule` is the Angular part of our hybrid application and the `ng1AppModule` is the
|
||||
* AngularJS part.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts" region="angular-setup"></code-example>
|
||||
*
|
||||
* Once this is done we can get hold of services via the Angular `Injector` as normal.
|
||||
* Services that are (or have dependencies on) an upgraded AngularJS service, will be instantiated
|
||||
* as needed by the AngularJS `$injector`.
|
||||
*
|
||||
* In the following code snippet, `HeroesService` is an Angular service that depends upon an
|
||||
* AngularJS service, `titleCase`.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts" region="angular-spec"></code-example>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* This helper is for testing services not Components.
|
||||
* For Component testing you must still bootstrap a hybrid app. See `UpgradeModule` or
|
||||
* `downgradeModule` for more information.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The resulting configuration does not wire up AngularJS digests to Zone hooks. It is the
|
||||
* responsibility of the test writer to call `$rootScope.$apply`, as necessary, to trigger
|
||||
* AngularJS handlers of async events from Angular.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The helper sets up global variables to hold the shared Angular and AngularJS injectors.
|
||||
*
|
||||
* * Only call this helper once per spec.
|
||||
* * Do not use `createAngularTestingModule` in the same spec as `createAngularJSTestingModule`.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* Here is the example application and its unit tests that use `createAngularTestingModule`
|
||||
* and `createAngularJSTestingModule`.
|
||||
*
|
||||
* <code-tabs>
|
||||
* <code-pane header="module.spec.ts" path="upgrade/static/ts/full/module.spec.ts"></code-pane>
|
||||
* <code-pane header="module.ts" path="upgrade/static/ts/full/module.ts"></code-pane>
|
||||
* </code-tabs>
|
||||
*
|
||||
*
|
||||
* @param angularJSModules a collection of the names of AngularJS modules to include in the
|
||||
* configuration.
|
||||
* @param [strictDi] whether the AngularJS injector should have `strictDI` enabled.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function createAngularTestingModule(
|
||||
angularJSModules: string[], strictDi?: boolean): Type<any> {
|
||||
angular.module_('$$angularJSTestingModule', angularJSModules)
|
||||
.constant(UPGRADE_APP_TYPE_KEY, UpgradeAppType.Static)
|
||||
.factory(INJECTOR_KEY, () => injector);
|
||||
$injector = angular.injector(['ng', '$$angularJSTestingModule'], strictDi);
|
||||
return AngularTestingModule;
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injector} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
import * as ng from '../../../src/common/src/angular1';
|
||||
import {$INJECTOR, INJECTOR_KEY, UPGRADE_APP_TYPE_KEY} from '../../../src/common/src/constants';
|
||||
import {UpgradeAppType} from '../../../src/common/src/util';
|
||||
|
||||
|
||||
/**
|
||||
* A helper function to use when unit testing AngularJS services that depend upon downgraded Angular
|
||||
* services.
|
||||
*
|
||||
* This function returns an AngularJS module that is configured to wire up the AngularJS and Angular
|
||||
* injectors without the need to actually bootstrap a hybrid application.
|
||||
* This makes it simpler and faster to unit test services.
|
||||
*
|
||||
* Use the returned AngularJS module in a call to
|
||||
* [`angular.mocks.module`](https://docs.angularjs.org/api/ngMock/function/angular.mock.module) to
|
||||
* include this module in the unit test injector.
|
||||
*
|
||||
* In the following code snippet, we are configuring the `$injector` with two modules:
|
||||
* The AngularJS `ng1AppModule`, which is the AngularJS part of our hybrid application and the
|
||||
* `Ng2AppModule`, which is the Angular part.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts"
|
||||
* region="angularjs-setup"></code-example>
|
||||
*
|
||||
* Once this is done we can get hold of services via the AngularJS `$injector` as normal.
|
||||
* Services that are (or have dependencies on) a downgraded Angular service, will be instantiated as
|
||||
* needed by the Angular root `Injector`.
|
||||
*
|
||||
* In the following code snippet, `heroesService` is a downgraded Angular service that we are
|
||||
* accessing from AngularJS.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts"
|
||||
* region="angularjs-spec"></code-example>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* This helper is for testing services not components.
|
||||
* For Component testing you must still bootstrap a hybrid app. See `UpgradeModule` or
|
||||
* `downgradeModule` for more information.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The resulting configuration does not wire up AngularJS digests to Zone hooks. It is the
|
||||
* responsibility of the test writer to call `$rootScope.$apply`, as necessary, to trigger
|
||||
* AngularJS handlers of async events from Angular.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The helper sets up global variables to hold the shared Angular and AngularJS injectors.
|
||||
*
|
||||
* * Only call this helper once per spec.
|
||||
* * Do not use `createAngularJSTestingModule` in the same spec as `createAngularTestingModule`.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* Here is the example application and its unit tests that use `createAngularTestingModule`
|
||||
* and `createAngularJSTestingModule`.
|
||||
*
|
||||
* <code-tabs>
|
||||
* <code-pane header="module.spec.ts" path="upgrade/static/ts/full/module.spec.ts"></code-pane>
|
||||
* <code-pane header="module.ts" path="upgrade/static/ts/full/module.ts"></code-pane>
|
||||
* </code-tabs>
|
||||
*
|
||||
*
|
||||
* @param angularModules a collection of Angular modules to include in the configuration.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function createAngularJSTestingModule(angularModules: any[]): string {
|
||||
return ng.module_('$$angularJSTestingModule', [])
|
||||
.constant(UPGRADE_APP_TYPE_KEY, UpgradeAppType.Static)
|
||||
.factory(
|
||||
INJECTOR_KEY,
|
||||
[
|
||||
$INJECTOR,
|
||||
($injector: ng.IInjectorService) => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: angularModules,
|
||||
providers: [{provide: $INJECTOR, useValue: $injector}]
|
||||
});
|
||||
return TestBed.get(Injector);
|
||||
}
|
||||
])
|
||||
.name;
|
||||
}
|
Reference in New Issue
Block a user