Provides the structure supported for options to pass into the configureGoogleMapsTestingModule()
function.
testing/helpers/setup.ts
Properties |
|
beforeComponentInit |
beforeComponentInit:
|
Type: function
|
Optional |
(Optional) A function to execute before the component is created. Example use case could be spying on a component's constructor. |
createTestModuleMetadata |
createTestModuleMetadata:
|
Type: function
|
Optional |
(Optional) A function that will define the test module imports and providers for the test.
Default is the |
customize |
customize:
|
Type: function
|
Optional |
(Optional) A function used to apply additional changes to the module definition before creating the TestBed. |
spies |
spies:
|
Type: literal type
|
Optional |
(Optional) Configures the automation of jest spies. |
import { TestModuleMetadata, TestBed, ComponentFixture } from '@angular/core/testing';
import { DebugElement, ElementRef, Type } from '@angular/core';
import { GoogleMapsModule, GoogleMapsApiService, GoogleMapsComponentApiService } from '@bespunky/angular-google-maps/core';
/**
* Creates a `TestModuleMetadata` object that can be passed into `TestBed.configureTestingModule()` in order to
* imprort the `GoogleMapsModule` **from the @bespunky/angular-google-maps/core package**, which automatically provides
* `NoOpGoogleMapsApiLoader` as the `GoogleMapsApiLoader` token.
*
* @export
* @returns {TestModuleMetadata} A TestBed-ready module configuration.
*/
export function createGoogleMapsTestModuleMetadata(): TestModuleMetadata
{
return {
imports : [GoogleMapsModule.forRoot()],
providers: []
};
}
/**
* Creates a jest spy on the `runOutsideAngular()`, `runInsideAngular()`, `runOutsideAngularWhenReady()` or `runInsideAngularWhenReady()` method of the api which fakes its execution.
* The fake implementation skips actually running the code outside/outside of angular and proceeds with executing
* it directly.
*
* @export
* @param {GoogleMapsApiService} api The api instance to spy on.
* @returns {jest.SpyInstance} A jest spy which can be used to count calls to `api.runOutsideAngular()`.
*/
export function fakeTheRunXsideAngularMethod(api: GoogleMapsApiService, methodName: 'runInsideAngular' | 'runOutsideAngular' | 'runInsideAngularWhenReady' | 'runOutsideAngularWhenReady'): jest.SpyInstance
{
return jest.spyOn(api, methodName).mockImplementation((fn: () => any) => fn());
}
/**
* Provides the structure supported for options to pass into the `configureGoogleMapsTestingModule()` function.
*
* @export
* @interface GoogleMapsTestingModuleConfigOptions
* @template TComponent
*/
export interface IGoogleMapsTestingModuleConfigOptions<TComponent = any>
{
/**
* (Optional) A function that will define the test module imports and providers for the test.
* Default is the `createGoogleMapsTestModuleMetadata()` function.
*/
createTestModuleMetadata?: () => TestModuleMetadata
/** (Optional) A function used to apply additional changes to the module definition before creating the TestBed. */
customize?: (moduleDef: TestModuleMetadata) => void;
/**
* (Optional) The type of component being tested. If specified, will declare the component, compile it, and extract
* the fixture, component, debugElement, and the native element objects.
*/
componentType?: Type<TComponent>,
/** (Optional) A function to execute before the component is created. Example use case could be spying on a component's constructor. */
beforeComponentInit?: (api: GoogleMapsApiService, componentApi: GoogleMapsComponentApiService) => void,
/** (Optional) Configures the automation of jest spies. */
spies?: {
/** `true` to fake the execution of `api.runInsideAngular()` (@see `fakeTheRunXsideAngularMethod()`); `false` to spy and call through. Default is `true`. */
fakeRunInsideAngular?: boolean,
/** `true` to fake the execution of `api.runOutsideAngular()` (@see `fakeTheRunXsideAngularMethod()`); `false` to spy and call through. Default is `true`. */
fakeRunOutsideAngular?: boolean,
/** `true` to fake the execution of `api.runInsideAngularWhenReady()` (@see `fakeTheRunXsideAngularMethod()`); `false` to spy and call through. Default is `true`. */
fakeRunInsideAngularWhenReady?: boolean,
/** `true` to fake the execution of `api.runOutsideAngularWhenReady()` (@see `fakeTheRunXsideAngularMethod()`); `false` to spy and call through. Default is `true`. */
fakeRunOutsideAngularWhenReady?: boolean
}
}
/** The default configuration for `configureGoogleMapsTestingModule()` for options not provided. */
const defaultModuleConfigOptions: IGoogleMapsTestingModuleConfigOptions = {
createTestModuleMetadata: createGoogleMapsTestModuleMetadata,
spies: {
fakeRunInsideAngular : true,
fakeRunOutsideAngular : true,
fakeRunInsideAngularWhenReady : true,
fakeRunOutsideAngularWhenReady: true
}
};
/**
* Configures a basic testing module with common definitions for Google Maps components and extracts useful tools and services.
* This should allow faster setup without the redundancy of declarations and extractions of services.
* After calling this function, the caller can simply deconstruct the tools and use them.
*
* @example let { api, component } = createGoogleMapsTestingModule({ componentType: GoogleMapsComponent });
* @export
* @template TComponent The type of the component being tested (if there is a component).
* @param {IGoogleMapsTestingModuleConfigOptions} [options] (Optional) The options for the configuring the test module.
* @returns The created tools and services, ready to use.
*/
export async function configureGoogleMapsTestingModule<TComponent>(options?: IGoogleMapsTestingModuleConfigOptions)
{
let fixture : ComponentFixture<TComponent>;
let component : TComponent;
let debugElement: DebugElement;
let element : ElementRef;
options = Object.assign({}, defaultModuleConfigOptions, options);
// Create the basic testing configuration
const moduleConfig = options.createTestModuleMetadata();
// Get the type of the component being compiled, if there is one
const componentType = options?.componentType;
// If there is a component to compile, declare it
if (componentType)
moduleConfig.declarations = [options.componentType];
// If there are any additional customizations to be done to the module definition, run them
if (options.customize)
options.customize(moduleConfig);
// Create the TestBed
const testBed = TestBed.configureTestingModule(moduleConfig);
// Retrieve useful services and tools
const api = TestBed.inject(GoogleMapsApiService);
const componentApi = TestBed.inject(GoogleMapsComponentApiService);
const runInsideAngular = options.spies.fakeRunInsideAngular ? fakeTheRunXsideAngularMethod(api, 'runInsideAngular') : jest.spyOn(api, 'runInsideAngular');
const runInsideAngularWhenReady = options.spies.fakeRunInsideAngular ? fakeTheRunXsideAngularMethod(api, 'runInsideAngularWhenReady') : jest.spyOn(api, 'runInsideAngularWhenReady');
const runOutsideAngular = options.spies.fakeRunOutsideAngular ? fakeTheRunXsideAngularMethod(api, 'runOutsideAngular') : jest.spyOn(api, 'runOutsideAngular');
const runOutsideAngularWhenReady = options.spies.fakeRunOutsideAngular ? fakeTheRunXsideAngularMethod(api, 'runOutsideAngularWhenReady') : jest.spyOn(api, 'runOutsideAngularWhenReady');
const spies = { runInsideAngular, runOutsideAngular, runInsideAngularWhenReady, runOutsideAngularWhenReady };
if (options.beforeComponentInit)
options.beforeComponentInit(api, componentApi);
// If a component is being tested, compile it and retrieve its relevant instances
if (componentType)
{
await testBed.compileComponents();
fixture = TestBed.createComponent(componentType);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
element = debugElement.nativeElement;
}
// Return all extracted services and objects for easier use
return { fixture, component, debugElement, element, api, componentApi, spies };
}