Skip to content

Commit 0cc77ac

Browse files
feat(jest): add createMock (#30)
1 parent 52131ee commit 0cc77ac

File tree

4 files changed

+90
-1
lines changed

4 files changed

+90
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Type, Provider } from '@angular/core';
2+
3+
export type Mock<T> = T & { [K in keyof T]: T[K] & jest.Mock };
4+
5+
export function createMock<T>(type: Type<T>): Mock<T> {
6+
const mock: any = {};
7+
8+
function mockFunctions(proto: any) {
9+
if (!proto) {
10+
return;
11+
}
12+
13+
for (const prop of Object.getOwnPropertyNames(proto)) {
14+
if (prop === 'constructor') {
15+
continue;
16+
}
17+
18+
const descriptor = Object.getOwnPropertyDescriptor(proto, prop);
19+
if (typeof descriptor.value === 'function') {
20+
mock[prop] = jest.fn();
21+
}
22+
}
23+
24+
mockFunctions(Object.getPrototypeOf(proto));
25+
}
26+
27+
mockFunctions(type.prototype);
28+
29+
return mock;
30+
}
31+
32+
export function provideMock<T>(type: Type<T>): Provider {
33+
return {
34+
provide: type,
35+
useFactory: () => createMock(type),
36+
};
37+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './configure-test-suite';
2+
export * from './create-mock';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { createMock, provideMock, Mock } from '../../src/jest-utils';
2+
import { render } from '../../src/public_api';
3+
import { Component } from '@angular/core';
4+
import { TestBed } from '@angular/core/testing';
5+
6+
class FixtureService {
7+
constructor(private foo: string, public bar: string) {}
8+
9+
print() {
10+
console.log(this.foo, this.bar);
11+
}
12+
}
13+
14+
@Component({
15+
selector: 'fixture',
16+
template: `
17+
<button (click)="print()">Print</button>
18+
`,
19+
})
20+
export class FixtureComponent {
21+
constructor(private service: FixtureService) {}
22+
23+
print() {
24+
this.service.print();
25+
}
26+
}
27+
28+
it('mocks all functions', () => {
29+
const mock = createMock(FixtureService);
30+
expect(mock.print.mock).toBeDefined();
31+
});
32+
33+
it('provides a mock service', async () => {
34+
const { click, getByText } = await render(FixtureComponent, {
35+
providers: [provideMock(FixtureService)],
36+
});
37+
const service = TestBed.get<FixtureService>(FixtureService);
38+
39+
click(getByText('Print'));
40+
expect(service.print).toHaveBeenCalledTimes(1);
41+
});
42+
43+
it('is possible to write a mock implementation', async done => {
44+
const { click, getByText } = await render(FixtureComponent, {
45+
providers: [provideMock(FixtureService)],
46+
});
47+
48+
const service = TestBed.get<FixtureService>(FixtureService) as Mock<FixtureService>;
49+
service.print.mockImplementation(() => done());
50+
51+
click(getByText('Print'));
52+
});

projects/testing-library/tests/providers/module-provider.spec.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Injectable } from '@angular/core';
22
import { Component } from '@angular/core';
33
import { render } from '../../src/public_api';
4-
import { TestBed } from '@angular/core/testing';
54

65
// tslint:disable: no-use-before-declare
76
test('shows the service value', async () => {

0 commit comments

Comments
 (0)