Skip to content

Commit 6905d52

Browse files
John Crowsonbrandonroberts
authored andcommitted
feat(schematics): add option to use MockStore in container tests (#2029)
Closes #2028
1 parent 14410c6 commit 6905d52

File tree

8 files changed

+96
-17
lines changed

8 files changed

+96
-17
lines changed

modules/schematics/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ npm_package(
3333
"**/src/*/files/**/*",
3434
"**/src/*/common-files/**/*",
3535
"**/src/*/creator-files/**/*",
36+
"**/src/*/integration-files/**/*",
3637
"**/schema.json",
3738
"**/migration.json",
3839
]),
@@ -56,6 +57,7 @@ ts_test_library(
5657
"**/src/*/files/**/*",
5758
"**/src/*/common-files/**/*",
5859
"**/src/*/creator-files/**/*",
60+
"**/src/*/integration-files/**/*",
5961
"**/*.json",
6062
]),
6163
deps = [

modules/schematics/src/container/files/__name@dasherize@if-flat__/__name@dasherize__.component.spec.ts.template

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
22

33
import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';
4-
import { Store, StoreModule } from '@ngrx/store';
4+
import { provideMockStore, MockStore } from '@ngrx/store/testing';
55

66
describe('<%= classify(name) %>Component', () => {
77
let component: <%= classify(name) %>Component;
88
let fixture: ComponentFixture<<%= classify(name) %>Component>;
9-
let store: Store<any>;
9+
let store: MockStore<any>;
1010

1111
beforeEach(async() => {
1212
TestBed.configureTestingModule({
13-
imports: [ StoreModule.forRoot({}) ],
13+
providers: [ provideMockStore() ],
1414
declarations: [ <%= classify(name) %>Component ]
1515
});
1616

@@ -22,7 +22,6 @@ describe('<%= classify(name) %>Component', () => {
2222
component = fixture.componentInstance;
2323
store = TestBed.get<Store>(Store);
2424

25-
spyOn(store, 'dispatch').and.callThrough();
2625
fixture.detectChanges();
2726
});
2827

modules/schematics/src/container/index.spec.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,29 @@ describe('Container Schematic', () => {
110110
});
111111

112112
it('should update the component spec', async () => {
113-
const options = { ...defaultOptions, spec: true };
113+
const options = { ...defaultOptions, spec: true, testDepth: 'unit' };
114114
const tree = await schematicRunner
115115
.runSchematicAsync('container', options, appTree)
116116
.toPromise();
117117
const content = tree.readContent(
118118
`${projectPath}/src/app/foo/foo.component.spec.ts`
119119
);
120120
expect(content).toMatch(
121-
/import { Store, StoreModule } from '@ngrx\/store';/
121+
/import { provideMockStore, MockStore } from '@ngrx\/store\/testing';/
122122
);
123123
});
124124

125+
it('should use the provideMockStore helper if unit', async () => {
126+
const options = { ...defaultOptions, spec: true, testDepth: 'unit' };
127+
const tree = await schematicRunner
128+
.runSchematicAsync('container', options, appTree)
129+
.toPromise();
130+
const content = tree.readContent(
131+
`${projectPath}/src/app/foo/foo.component.spec.ts`
132+
);
133+
expect(content).toMatch(/providers: \[ provideMockStore\(\) \]/);
134+
});
135+
125136
it('should inject Store correctly', async () => {
126137
const options = { ...defaultOptions, spec: true };
127138
const tree = await schematicRunner
@@ -132,4 +143,17 @@ describe('Container Schematic', () => {
132143
);
133144
expect(content).toMatch(/store = TestBed\.get<Store>\(Store\);/);
134145
});
146+
147+
it('should use StoreModule if integration test', async () => {
148+
const options = { ...defaultOptions, spec: true };
149+
const tree = await schematicRunner
150+
.runSchematicAsync('container', options, appTree)
151+
.toPromise();
152+
const content = tree.readContent(
153+
`${projectPath}/src/app/foo/foo.component.spec.ts`
154+
);
155+
expect(content).toMatch(
156+
/import { Store, StoreModule } from '@ngrx\/store';/
157+
);
158+
});
135159
});

modules/schematics/src/container/index.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,20 @@ export default function(options: ContainerOptions): Rule {
136136
options
137137
);
138138

139-
const templateSource = apply(url('./files'), [
140-
options.spec
141-
? noop()
142-
: filter(path => !path.endsWith('.spec.ts.template')),
143-
applyTemplates({
144-
'if-flat': (s: string) => (options.flat ? '' : s),
145-
...stringUtils,
146-
...(options as object),
147-
} as any),
148-
move(parsedPath.path),
149-
]);
139+
const templateSource = apply(
140+
url(options.testDepth === 'unit' ? './files' : './integration-files'),
141+
[
142+
options.spec
143+
? noop()
144+
: filter(path => !path.endsWith('.spec.ts.template')),
145+
applyTemplates({
146+
'if-flat': (s: string) => (options.flat ? '' : s),
147+
...stringUtils,
148+
...(options as object),
149+
} as any),
150+
move(parsedPath.path),
151+
]
152+
);
150153

151154
return chain([
152155
externalSchematic('@schematics/angular', 'component', {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';
4+
import { Store, StoreModule } from '@ngrx/store';
5+
6+
describe('<%= classify(name) %>Component', () => {
7+
let component: <%= classify(name) %>Component;
8+
let fixture: ComponentFixture<<%= classify(name) %>Component>;
9+
let store: Store<any>;
10+
11+
beforeEach(async() => {
12+
TestBed.configureTestingModule({
13+
imports: [ StoreModule.forRoot({}) ],
14+
declarations: [ <%= classify(name) %>Component ]
15+
});
16+
17+
await TestBed.compileComponents();
18+
});
19+
20+
beforeEach(() => {
21+
fixture = TestBed.createComponent(<%= classify(name) %>Component);
22+
component = fixture.componentInstance;
23+
store = TestBed.get<Store>(Store);
24+
25+
spyOn(store, 'dispatch').and.callThrough();
26+
fixture.detectChanges();
27+
});
28+
29+
it('should create', () => {
30+
expect(component).toBeTruthy();
31+
});
32+
});

modules/schematics/src/container/schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@
9797
"type": "string",
9898
"default": "State",
9999
"description": "Specifies the interface for the state."
100+
},
101+
"testDepth": {
102+
"description":
103+
"Specifies whether to create a unit test or an integration test.",
104+
"enum": ["unit", "integration"],
105+
"type": "string",
106+
"default": "integration"
100107
}
101108
},
102109
"required": []

modules/schematics/src/container/schema.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,9 @@ export interface Schema {
6868
* Specifies the interface for the state
6969
*/
7070
stateInterface?: string;
71+
72+
/**
73+
* Specifies whether to create a unit test or an integration test.
74+
*/
75+
testDepth?: string;
7176
}

projects/ngrx.io/content/guide/schematics/container.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ Provide the name of the interface exported for your state interface
3535
- Type: `string`
3636
- Default: `State`
3737

38+
Specifies whether to create a unit test or an integration test
39+
40+
- `--testDepth`
41+
- Type: `string`
42+
- Values: `unit|integration`
43+
- Default: `integration`
44+
3845
## Examples
3946

4047
Generate a `UsersPage` container component with your reducers imported and the `Store` typed a custom interface named `MyState`.

0 commit comments

Comments
 (0)