From 570af049e0a6dd95d3c60d7dba14b3848a13e6c1 Mon Sep 17 00:00:00 2001 From: va-stefanek Date: Sat, 23 Jan 2021 09:08:13 +0100 Subject: [PATCH] fix: override providers for createComponentFactory --- .../src/lib/spectator/create-factory.ts | 53 ++++++++++++------- .../spectator/test/override-providers.spec.ts | 43 +++++++++++++++ 2 files changed, 77 insertions(+), 19 deletions(-) create mode 100644 projects/spectator/test/override-providers.spec.ts diff --git a/projects/spectator/src/lib/spectator/create-factory.ts b/projects/spectator/src/lib/spectator/create-factory.ts index 26afffe4..727710d0 100644 --- a/projects/spectator/src/lib/spectator/create-factory.ts +++ b/projects/spectator/src/lib/spectator/create-factory.ts @@ -1,4 +1,4 @@ -import { Provider, Type } from '@angular/core'; +import { Type } from '@angular/core'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; @@ -7,6 +7,7 @@ import { setProps } from '../internals/query'; import * as customMatchers from '../matchers'; import { addMatchers } from '../core'; import { isType } from '../types'; +import { ModuleMetadata } from '../base/initial-module'; import { initialSpectatorModule } from './initial-module'; import { getSpectatorDefaultOptions, SpectatorOptions } from './options'; @@ -73,30 +74,19 @@ export function createComponentFactory(typeOrOptions: Type | SpectatorOpti const moduleMetadata = initialSpectatorModule(options); - beforeEach( - waitForAsync(() => { - addMatchers(customMatchers); - TestBed.configureTestingModule(moduleMetadata).overrideModule(BrowserDynamicTestingModule, { - set: { - entryComponents: moduleMetadata.entryComponents - } - }); - - overrideModules(options); - - overrideComponentIfProviderOverridesSpecified(options); - - TestBed.compileComponents(); - }) - ); + beforeEach(waitForAsync(() => { + configureAndCompileTestingModule(moduleMetadata, options); + })); return (overrides?: SpectatorOverrides) => { const defaults: SpectatorOverrides = { props: {}, detectChanges: true, providers: [] }; const { detectChanges, props, providers } = { ...defaults, ...overrides }; if (providers && providers.length) { - providers.forEach((provider: Provider) => { - TestBed.overrideProvider((provider as any).provide, provider as any); + TestBed.resetTestingModule(); + initializeTestingModule({ + ...options, + providers }); } @@ -118,3 +108,28 @@ function createSpectator(options: Required>, props?: Part return new Spectator(fixture, debugElement, component, debugElement.nativeElement); } + +function initializeTestingModule(typeOrOptions: Type | SpectatorOptions): void { + const options = isType(typeOrOptions) + ? getSpectatorDefaultOptions({ component: typeOrOptions }) + : getSpectatorDefaultOptions(typeOrOptions); + + const moduleMetadata = initialSpectatorModule(options); + + configureAndCompileTestingModule(moduleMetadata, options); +} + +function configureAndCompileTestingModule(moduleMetadata: ModuleMetadata, options: Required>): void { + addMatchers(customMatchers); + TestBed.configureTestingModule(moduleMetadata).overrideModule(BrowserDynamicTestingModule, { + set: { + entryComponents: moduleMetadata.entryComponents + } + }); + + overrideModules(options); + + overrideComponentIfProviderOverridesSpecified(options); + + TestBed.compileComponents(); +} diff --git a/projects/spectator/test/override-providers.spec.ts b/projects/spectator/test/override-providers.spec.ts new file mode 100644 index 00000000..964695af --- /dev/null +++ b/projects/spectator/test/override-providers.spec.ts @@ -0,0 +1,43 @@ +import { createComponentFactory, Spectator } from '@ngneat/spectator'; +import { Component, InjectionToken } from '@angular/core'; + +@Component({ + selector: 'lib-test', + template: '
test
' +}) +class TestComponent {} + +class StateMock {} + +class AnotherStateMock {} + +export const STATE = new InjectionToken('Angular State'); + +describe('Override providers', () => { + let spectator: Spectator; + + const createComponent = createComponentFactory({ + component: TestComponent, + providers: [{ provide: STATE, useClass: AnotherStateMock }] + }); + + beforeEach(() => (spectator = createComponent())); + + it('should create', () => { + expect(spectator).toBeTruthy(); + }); + + it('should get the correct instance of STATE', () => { + const service = spectator.inject(STATE); + + expect(service instanceof AnotherStateMock).toBeTrue(); + }); + + it('should get the mocked instance of STATE injection token', () => { + spectator = createComponent({ providers: [{ provide: STATE, useClass: StateMock }] }); + + const service = spectator.inject(STATE); + + expect(service instanceof StateMock).toBeTrue(); + }); +});