Skip to content

Commit

Permalink
fix: override providers for createComponentFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
va-stefanek committed Jan 23, 2021
1 parent dc3ee10 commit d527299
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 15 deletions.
47 changes: 32 additions & 15 deletions projects/spectator/src/lib/spectator/create-factory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Provider, Type } from '@angular/core';
import { Type } from '@angular/core';
import { async, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';

Expand All @@ -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';
Expand Down Expand Up @@ -74,27 +75,18 @@ export function createComponentFactory<C>(typeOrOptions: Type<C> | SpectatorOpti
const moduleMetadata = initialSpectatorModule<C>(options);

beforeEach(async(() => {
addMatchers(customMatchers);
TestBed.configureTestingModule(moduleMetadata).overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: moduleMetadata.entryComponents
}
});

overrideModules(options);

overrideComponentIfProviderOverridesSpecified(options);

TestBed.compileComponents();
configureAndCompileTestingModule(moduleMetadata, options);
}));

return (overrides?: SpectatorOverrides<C>) => {
const defaults: SpectatorOverrides<C> = { 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
});
}

Expand All @@ -116,3 +108,28 @@ function createSpectator<C>(options: Required<SpectatorOptions<C>>, props?: Part

return new Spectator(fixture, debugElement, component, debugElement.nativeElement);
}

function initializeTestingModule<C>(typeOrOptions: Type<C> | SpectatorOptions<C>): void {
const options = isType(typeOrOptions)
? getSpectatorDefaultOptions<C>({ component: typeOrOptions })
: getSpectatorDefaultOptions(typeOrOptions);

const moduleMetadata = initialSpectatorModule<C>(options);

configureAndCompileTestingModule(moduleMetadata, options);
}

function configureAndCompileTestingModule<C>(moduleMetadata: ModuleMetadata, options: Required<SpectatorOptions<C>>): void {
addMatchers(customMatchers);
TestBed.configureTestingModule(moduleMetadata).overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: moduleMetadata.entryComponents
}
});

overrideModules(options);

overrideComponentIfProviderOverridesSpecified(options);

TestBed.compileComponents();
}
43 changes: 43 additions & 0 deletions projects/spectator/test/override-providers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { createComponentFactory, Spectator } from '@ngneat/spectator';
import { Component, InjectionToken } from '@angular/core';

@Component({
selector: 'lib-test',
template: '<div>test</div>'
})
class TestComponent {}

class StateMock {}

class AnotherStateMock {}

export const STATE = new InjectionToken<any>('Angular State');

describe('Override providers', () => {
let spectator: Spectator<TestComponent>;

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();
});
});

0 comments on commit d527299

Please sign in to comment.