-
-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(mock-builder): respecting forward-ref and modules with providers #…
- Loading branch information
Showing
13 changed files
with
686 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--- | ||
title: How to test usage of ngrx in Angular applications | ||
sidebar_label: NGRX | ||
--- | ||
|
||
`ng-mocks` perfectly mocks `NGRX` modules. However, there are might be issues if some of them should be kept. | ||
|
||
Besides `StoreModule`, which is an entry point to configure effects and reducers, | ||
under the hood `NGRX` uses four other modules, and these modules should be configured in `MockBuilder`: | ||
|
||
- `StoreRootModule` | ||
- `StoreFeatureModule` | ||
* `EffectsRootModule` | ||
* `EffectsFeatureModule` | ||
|
||
Or a simple value is to rely on `.ngModule` property: | ||
|
||
- `StoreModule.forRoot().ngModule` | ||
- `StoreModule.forFeature().ngModule` | ||
* `EffectsModule.forRoot().ngModule` | ||
* `EffectsModule.forFeature().ngModule` | ||
|
||
Let's imagine that we want to keep `StoreModule` in a test, | ||
then we should pass the modules into [`.keep`](../../api/MockBuilder.md#keep): | ||
|
||
```ts | ||
beforeEach(() => | ||
MockBuilder(MyComponent, MyModule) | ||
.keep(StoreRootModule) | ||
.keep(StoreFeatureModule) | ||
.keep(EffectsRootModule) | ||
.keep(EffectsFeatureModule) | ||
); | ||
``` | ||
|
||
or | ||
|
||
```ts | ||
beforeEach(() => | ||
MockBuilder(MyComponent, MyModule) | ||
.keep(StoreModule.forRoot().ngModule) | ||
.keep(StoreModule.forFeature().ngModule) | ||
.keep(EffectsModule.forRoot().ngModule) | ||
.keep(EffectsModule.forFeature().ngModule) | ||
); | ||
``` | ||
|
||
Please pay attention that `MyModule` or its imports should import `.forRoot` and `.forFeature`, | ||
otherwise we need to call [`.keep`](../../api/MockBuilder.md#keep) as usually: | ||
|
||
```ts | ||
beforeEach(() => | ||
MockBuilder(MyComponent, MyModule) | ||
.keep(StoreModule.forRoot()) | ||
.keep(StoreModule.forFeature()) | ||
.keep(EffectsModule.forRoot()) | ||
.keep(EffectsModule.forFeature()) | ||
); | ||
``` | ||
|
||
## Lazy loaded modules with `.forFeature()` | ||
|
||
When we want to test a lazy loaded module, it means there is no import of `.forRoot()` calls, | ||
because they are in a parent module. | ||
Therefore, the `.forRoot()` calls should be added manually without any special configuration: | ||
|
||
```ts | ||
beforeEach(() => | ||
MockBuilder(SomeComponent, LazyLoadedModule) | ||
// providing root tools | ||
.keep(StoreModule.forRoot()) | ||
.keep(EffectsModule.forRoot()) | ||
// keeping lazy loaded module definitions | ||
.keep(StoreFeatureModule) | ||
.keep(EffectsFeatureModule) | ||
); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 23 additions & 15 deletions
38
libs/ng-mocks/src/lib/mock-builder/promise/init-ng-modules.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,40 @@ | ||
import { mapValues } from '../../common/core.helpers'; | ||
import { flatten, mapValues } from '../../common/core.helpers'; | ||
import funcGetProvider from '../../common/func.get-provider'; | ||
import { isNgDef } from '../../common/func.is-ng-def'; | ||
import ngMocksUniverse from '../../common/ng-mocks-universe'; | ||
|
||
import initModule from './init-module'; | ||
import skipInitModule from './skip-init-module'; | ||
import { BuilderData, NgMeta } from './types'; | ||
|
||
const handleDef = ({ imports, declarations }: NgMeta, def: any, defProviders: Map<any, any>): void => { | ||
if (isNgDef(def, 'm')) { | ||
const extendedDef = initModule(def, defProviders); | ||
imports.push(extendedDef); | ||
|
||
// adding providers to touches | ||
if (typeof extendedDef === 'object' && extendedDef.providers) { | ||
for (const provider of flatten(extendedDef.providers)) { | ||
ngMocksUniverse.touches.add(funcGetProvider(provider)); | ||
} | ||
} | ||
} else { | ||
declarations.push(ngMocksUniverse.getBuildDeclaration(def)); | ||
} | ||
|
||
ngMocksUniverse.touches.add(def); | ||
}; | ||
|
||
export default ({ configDef, keepDef, mockDef, replaceDef }: BuilderData, defProviders: Map<any, any>): NgMeta => { | ||
const { imports, declarations, providers }: NgMeta = { imports: [], declarations: [], providers: [] }; | ||
const meta: NgMeta = { imports: [], declarations: [], providers: [] }; | ||
|
||
// Adding suitable leftovers. | ||
for (const def of [...mapValues(mockDef), ...mapValues(keepDef), ...mapValues(replaceDef)]) { | ||
if (skipInitModule(def, configDef)) { | ||
continue; | ||
} | ||
|
||
if (isNgDef(def, 'm')) { | ||
imports.push(initModule(def, defProviders)); | ||
} else { | ||
declarations.push(ngMocksUniverse.getBuildDeclaration(def)); | ||
} | ||
|
||
ngMocksUniverse.touches.add(def); | ||
handleDef(meta, def, defProviders); | ||
} | ||
|
||
return { | ||
declarations, | ||
imports, | ||
providers, | ||
}; | ||
return meta; | ||
}; |
Oops, something went wrong.