-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Documentation request: how to setup State while testing Effects that use withLatestFrom #414
Comments
Have you setup the TestingModule with a store and a state? i.e.
|
@phillipzada If you need to test with different state values -- reconfiguring the test bed multiple times feels like a lot of work. In my own tests... I've resorted to dispatching actions that will updated the necessary state values... but it feels like a bad workaround. It would be ideal to have a way to set the state values without reconfiguring the test bed and without having to dispatch actions from your app. |
@phillipzada Yes, we have setup the TestModule. The main problem is that we can only setup one state here, as @nathanmarks notes. For now, we use the work around that Nathan suggests but it is a very brittle solution. It would be nice if there was a officially supported way to setup the test data in the Store. It would be nice if, for tests, we would be able to do something like:
|
Hey guys, What we've done is create meta reducer specifically for tests that updates the state for each test. Remembering you have a pretty good idea where your state should be at when a particular action is fired and picked up by an effect.
then during the test its injected into the beforeEach TestModule as so:
Note: if you append the file that contains the metaReducer with .spec.ts it will only get compiled in test runs. Then in your tests you have the following function that can be called from your tests
|
@bobvandenberge - In testing effects, If you are getting the state via store.select (which is recommended) you can inject only the provider in TestBed. You don't need to inject the full StoreModule.
And in test suite you can use Spy to give you any slice of store that you want:
|
@phillipzada @MikeSaprykin Thanks for the suggestions! We managed to solve the issue using an adapted version of the solution provided by Mike. We have a custom FakeStore that allows us to easily setup mock data for selectors. Next to that I adjusted our 2 questions/topics remain though (not sure if they are part of this issue):
For further reference, here is the complete code we use. FakeStore.ts:
effects.ts:
effects.spec.ts:
|
Thanks for this solution. I do think the "2 questions/topics" are worth more discussion. |
@bobvandenberge solution is very nice. But after I adopted it in my project I realised that it doesn't suitable for more complex cases. For example you have something like this in your effect class:
In general sometimes you can depend on store changes over time in your effects. One solution could be to call the original actions which will cause the corresponding store changes. It's a legit solution but it makes your effect test more dependant on your application structure, less isolated.
in your spec it looks somehow like this:
|
I ended up doing something like export class MockStore<T = any> extends Store<T> {
source = new BehaviorSubject<any>({});
overrideState(state: any) {
this.source.next(state);
}
} .spec.ts TestBed.configureTestingModule({
providers: [
{ provide: Store, useClass: MockStore },
]
});
beforeEach(() => {
store.overrideState({
route: MOCK_ROUTE_DATA_WITH_OVERRIDE
});
}); |
I was getting errors indicating that there was no initial state in my library tests. I found that in my library module I had to use the static |
Another option is to
|
@bobvandenberge how can i use this example if i use
we refactor it from this |
@FooPix we haven't upgraded yet so I don't have an answer for that. Once we upgrade and figure it out I will let you know. |
@rkorrelboom's approach can be used with whatever mock library you're using (ex: jest). The idea is to overwrite your store mock before you call |
Probably it make sense to add this or other acceptable solution to compiled module and add documentation for it. I spent 2 hours to write simple unit test for effect with |
@EugeneSnihovsky NgRx 7.0 introduced a |
Hey lads, I'm having some difficulties in unit testing an effect which uses |
Yes, this kind of documentation is indeed needed that too along with new Mockstore implementation. I don't think this should be closed unless, its new example is added. |
I've found the best way to do this is to use a Facade instead of injecting the Store into the effects. That way, you can easily mock only the things you want without having to deal with the whole Store. In effect:
In effect.spec:
|
I'm submitting a...
We recently started using ngrx. Current we use marbles to test our Effects which works great in almost all scenario's. We have come across our first scenario where we have to test an Effect that uses a value from the store. In the code we use
withLatestFrom
for this. The problem is that we cannot figure out how to get this working in the test. How can we setup test data in the store? Can we update the documentation with an example of this? I would be surprised if I am the only one facing this issue :).Code:
Snippit from Effects.ts
The text was updated successfully, but these errors were encountered: