Created
October 4, 2018 23:16
-
-
Save honsq90/dcf5783593c94084c83d4e34d93479b6 to your computer and use it in GitHub Desktop.
ngRx 6 Mock Store
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
import * as ngrxStore from '@ngrx/store'; | |
import { MemoizedSelector } from '@ngrx/store'; | |
import { BehaviorSubject, pipe } from 'rxjs'; | |
import { map } from 'rxjs/operators'; | |
interface SelectorMap { | |
[key: string]: MemoizedSelector<any, any>; | |
} | |
function getKeyByValue(object, value) { | |
return Object.keys(object).find(key => object[key] === value); | |
} | |
export class Ngrx6MockStore extends BehaviorSubject<any> { | |
private state: any = {}; | |
select; | |
constructor(private selectors: SelectorMap) { | |
super({}); | |
this.select = jest | |
.spyOn(ngrxStore, 'select') | |
.mockImplementation((selector) => { | |
const selectKey = getKeyByValue(this.selectors, selector); | |
return pipe( | |
map((state) => { | |
return state[selectKey]; | |
}) | |
); | |
}); | |
} | |
dispatch = jest.fn(); | |
mockNext(override: object): void { | |
this.state = { | |
...this.state, | |
...override, | |
}; | |
this.next(this.state); | |
} | |
} | |
export function provideMockStore<T>(selectors: SelectorMap) { | |
return [ | |
{ | |
provide: ngrxStore.Store, | |
useValue: new Ngrx6MockStore(selectors), | |
}, | |
]; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Following discussions from:
ngrx/platform#915
ngrx/platform#1027
Since the new injected Store is a
BehaviorSubject
and we've already tested our reducers, effects and selectors, this mock store is a very stripped down version on the proposed testing solution.Similar to some of the examples in the linked issue, this would allow us greater control over the various permutations of selector observables to test the component. This way we don't have to worry about setting up state via dispatching actions in our unit tests, all the component cares about is the contract set up with the NgRx selectors. If the internals of the selectors and/or the reducers were to change, we wouldn't have to update our test setup scripts.
Here's how you would utilise the mock store:
Your corresponding test would look like this: