Skip to content

Commit

Permalink
feat: providers for MockRender
Browse files Browse the repository at this point in the history
allows to override provider for a render context

closes #102
  • Loading branch information
satanTime committed May 9, 2020
1 parent b897ab9 commit cb656b7
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 8 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,14 @@ describe('MockModule', () => {
Providers simple way to render anything, change `@Inputs` and `@Outputs` of testing component, directives etc.

It returns `fixture` with a `point` property if a component class was passed.
The `fixture` belongs the middle component for the render,
when `fixture.point` points to the debug element of the testing component.
The `fixture` belongs to the middle component for the render,
when `fixture.point` points to the debugElement of the passed component.

The best thing here is that `fixture.point.componentInstance` is typed to the component's class.

If you want you can set providers for the render passing them via the 3rd parameter.
It is useful if you want to mock system tokens / services such as APP_INITIALIZER, DOCUMENT etc.

### Usage Example

```typescript
Expand Down Expand Up @@ -494,6 +497,9 @@ Add the next code to `src/test.ts` if you want all mocked methods and functions

```typescript
import 'ng-mocks/dist/jasmine';

// uncomment in case if you existing tests with spies.
// jasmine.getEnv().allowRespy(true);
```

In case of jest.
Expand Down
2 changes: 2 additions & 0 deletions karma-test-shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ import 'core-js/es7/reflect'; // tslint:disable-line
import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

jasmine.getEnv().allowRespy(true);

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
10 changes: 9 additions & 1 deletion lib/mock-render/mock-render.fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Component, EventEmitter, Inject, Input, Output } from '@angular/core';

@Component({
selector: 'render-real-component',
Expand All @@ -7,4 +8,11 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
export class RenderRealComponent {
@Output() click = new EventEmitter<{}>();
@Input() content = '';

public readonly document: Document;

constructor(@Inject(DOCUMENT) document: Document) {
this.document = document;
this.document.getElementById('test');
}
}
21 changes: 21 additions & 0 deletions lib/mock-render/mock-render.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import createSpy = jasmine.createSpy;
import { DOCUMENT } from '@angular/common';
import { TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { MockService } from '../mock-service';

import { MockRender } from './mock-render';
import { RenderRealComponent } from './mock-render.fixtures';

Expand Down Expand Up @@ -88,4 +91,22 @@ describe('MockRender', () => {
const fixture = MockRender(RenderRealComponent);
expect(fixture.point.componentInstance).toEqual(jasmine.any(RenderRealComponent));
});

it('returns pointer with a provided component', () => {
const document = MockService(Document);
spyOn(document, 'getElementById');
MockRender(
RenderRealComponent,
{},
{
providers: [
{
provide: DOCUMENT,
useValue: document,
},
],
}
);
expect(document.getElementById).toHaveBeenCalledWith('test');
});
});
18 changes: 13 additions & 5 deletions lib/mock-render/mock-render.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// tslint:disable:unified-signatures

import { Component, DebugElement, Type } from '@angular/core';
import { Component, DebugElement, Provider, Type } from '@angular/core';
import { ComponentFixture, getTestBed, TestBed } from '@angular/core/testing';

import { directiveResolver } from '../common/reflect';
Expand Down Expand Up @@ -30,10 +30,15 @@ export type DebugElementField =

export type DebugElementType<T> = { componentInstance: T } & Pick<DebugElement, DebugElementField>;

export interface IMockRenderOptions {
detectChanges?: boolean;
providers?: Provider[];
}

function MockRender<MComponent, TComponent extends { [key: string]: any }>(
template: Type<MComponent>,
params: TComponent,
detectChanges?: boolean
detectChanges?: boolean | IMockRenderOptions
): ComponentFixture<TComponent> & { point: DebugElementType<MComponent> };

// without params we shouldn't autocomplete any keys of any types.
Expand All @@ -44,7 +49,7 @@ function MockRender<MComponent>(
function MockRender<MComponent, TComponent extends { [key: string]: any }>(
template: string,
params: TComponent,
detectChanges?: boolean
detectChanges?: boolean | IMockRenderOptions
): ComponentFixture<TComponent>;

// without params we shouldn't autocomplete any keys of any types.
Expand All @@ -53,8 +58,10 @@ function MockRender<MComponent>(template: string): ComponentFixture<null>;
function MockRender<MComponent, TComponent extends { [key: string]: any }>(
template: string | Type<MComponent>,
params?: TComponent,
detectChanges = true
flags: boolean | IMockRenderOptions = true
): ComponentFixture<TComponent> {
const flagsObject: IMockRenderOptions = typeof flags === 'boolean' ? { detectChanges: flags } : flags;

let mockedTemplate = '';
if (typeof template === 'string') {
mockedTemplate = template;
Expand Down Expand Up @@ -84,6 +91,7 @@ function MockRender<MComponent, TComponent extends { [key: string]: any }>(
mockedTemplate += `></${selector}>`;
}
const options: Component = {
providers: flagsObject.providers,
selector: 'mock-render',
template: mockedTemplate,
};
Expand All @@ -107,7 +115,7 @@ function MockRender<MComponent, TComponent extends { [key: string]: any }>(

const fixture: any = TestBed.createComponent(component);

if (detectChanges) {
if (flagsObject.detectChanges) {
fixture.detectChanges();
}

Expand Down

0 comments on commit cb656b7

Please sign in to comment.