Skip to content

Commit c4c6250

Browse files
fix: providers on a module level (#26)
BREAKING CHANGE: Component providers should be provided via `componentProviders`.
1 parent dbbc95c commit c4c6250

File tree

6 files changed

+157
-48
lines changed

6 files changed

+157
-48
lines changed

projects/testing-library/src/lib/models.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface RenderOptions<C, Q extends Queries = typeof queries> {
1717
imports?: any[];
1818
schemas?: any[];
1919
componentProperties?: Partial<C>;
20+
componentProviders?: any[];
2021
queries?: Q;
2122
wrapper?: Type<any>;
2223
}

projects/testing-library/src/lib/testing-library.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export async function render<T>(
2828
queries,
2929
wrapper = WrapperComponent,
3030
componentProperties = {},
31+
componentProviders = [],
3132
} = renderOptions;
3233

3334
const isTemplate = typeof templateOrComponent === 'string';
@@ -40,9 +41,8 @@ export async function render<T>(
4041
schemas: [...schemas],
4142
});
4243

43-
if (providers) {
44-
// override services this way to have the service overridden at the component level
45-
providers
44+
if (componentProviders) {
45+
componentProviders
4646
.reduce((acc, provider) => acc.concat(provider), [])
4747
.forEach(p => {
4848
const { provide, ...provider } = p;

projects/testing-library/tests/component-provider/component-provider.spec.ts

-43
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { Injectable } from '@angular/core';
2+
import { Component } from '@angular/core';
3+
import { render } from '../../src/public_api';
4+
5+
// tslint:disable: no-use-before-declare
6+
test('shows the service value', async () => {
7+
const { getByText } = await render(FixtureComponent);
8+
9+
getByText('foo');
10+
});
11+
12+
test('shows the service value with template syntax', async () => {
13+
const { getByText } = await render('<fixture-component></fixture-component>', {
14+
declarations: [FixtureComponent],
15+
});
16+
17+
getByText('foo');
18+
});
19+
20+
test('shows the provided service value', async () => {
21+
const { getByText } = await render(FixtureComponent, {
22+
componentProviders: [
23+
{
24+
provide: Service,
25+
useValue: {
26+
foo() {
27+
return 'bar';
28+
},
29+
},
30+
},
31+
],
32+
});
33+
34+
getByText('bar');
35+
});
36+
37+
test('shows the provided service value with template syntax', async () => {
38+
const { getByText } = await render('<fixture-component></fixture-component>', {
39+
declarations: [FixtureComponent],
40+
componentProviders: [
41+
{
42+
provide: Service,
43+
useValue: {
44+
foo() {
45+
return 'bar';
46+
},
47+
},
48+
},
49+
],
50+
});
51+
52+
getByText('bar');
53+
});
54+
55+
@Injectable()
56+
export class Service {
57+
foo() {
58+
return 'foo';
59+
}
60+
}
61+
62+
@Component({
63+
selector: 'fixture-component',
64+
template: '{{service.foo()}}',
65+
providers: [Service],
66+
})
67+
export class FixtureComponent {
68+
constructor(public service: Service) {}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Injectable } from '@angular/core';
2+
import { Component } from '@angular/core';
3+
import { render } from '../../src/public_api';
4+
import { TestBed } from '@angular/core/testing';
5+
6+
// tslint:disable: no-use-before-declare
7+
test('shows the service value', async () => {
8+
const { getByText } = await render(FixtureComponent, {
9+
providers: [Service],
10+
});
11+
12+
getByText('foo');
13+
});
14+
15+
test('shows the service value with template syntax', async () => {
16+
const { getByText } = await render('<fixture-component></fixture-component>', {
17+
declarations: [FixtureComponent],
18+
providers: [Service],
19+
});
20+
21+
getByText('foo');
22+
});
23+
24+
test('shows the provided service value', async () => {
25+
const { getByText } = await render(FixtureComponent, {
26+
providers: [
27+
{
28+
provide: Service,
29+
useValue: {
30+
foo() {
31+
return 'bar';
32+
},
33+
},
34+
},
35+
],
36+
});
37+
38+
getByText('bar');
39+
});
40+
41+
test('shows the provided service value with template syntax', async () => {
42+
const { getByText } = await render('<fixture-component></fixture-component>', {
43+
declarations: [FixtureComponent],
44+
providers: [
45+
{
46+
provide: Service,
47+
useValue: {
48+
foo() {
49+
return 'bar';
50+
},
51+
},
52+
},
53+
],
54+
});
55+
56+
getByText('bar');
57+
});
58+
59+
@Injectable()
60+
export class Service {
61+
foo() {
62+
return 'foo';
63+
}
64+
}
65+
66+
@Component({
67+
selector: 'fixture-component',
68+
template: '{{service.foo()}}',
69+
})
70+
export class FixtureComponent {
71+
constructor(public service: Service) {}
72+
}

src/app/app.component.spec.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { AppComponent } from './app.component';
1+
import { TestBed } from '@angular/core/testing';
2+
import { Store } from '@ngrx/store';
3+
import { provideMockStore } from '@ngrx/store/testing';
24
import { render } from '@testing-library/angular';
35
import { configureJestSetup } from '@testing-library/angular/jest-utils';
4-
import { provideMockStore } from '@ngrx/store/testing';
6+
import { AppComponent } from './app.component';
57

68
configureJestSetup();
79

@@ -28,3 +30,11 @@ test(`should render title in a h1 tag`, async () => {
2830
});
2931
expect(container.querySelector('h1').textContent).toContain('Welcome to app!');
3032
});
33+
34+
test(`should be able to get the Store`, async () => {
35+
await render('<app-root></app-root>', {
36+
declarations: [AppComponent],
37+
providers: [provideMockStore()],
38+
});
39+
expect(TestBed.get(Store)).toBeDefined();
40+
});

0 commit comments

Comments
 (0)