Example:
myAwesomeEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAwesomeAction),
concatMap(action => of(action).pipe(
withLatestFrom(this.store$.pipe(select(myAwesomeSelector)))
)),
filter(([, myAwesomeValue]) => myAwesomeValue),
map(() => myNotThatAwesomeAction())
)
);
Few things to point out. As you can see the effect returns action only if the filter logic evaluates to true. That means the effect sometimes returns an action, sometimes it doesn't.
Is it a valid effect? Should I refrain from using filter operator in effect and replace it with if and a Noop action instead?
myAwesomeEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAwesomeAction),
concatMap(action =>
of(action).pipe(
withLatestFrom(
this.store$.pipe(select(myAwesomeSelector))
)
)
),
map(([, myAwesomeValue]) => {
if (myAwesomeValue) {
return myNotThatAwesomeAction();
}
return NoopAction();
})
)
);
The second example is easy to test:
it('should return myNotThatAwesomeAction when myAwesomeValue is true', done => {
store.overrideSelector(myAwesomeSelector, true);
myAwesomeEffect$().subscribe(res => {
expect(res).toEqual(myNotThatAwesomeAction());
done();
});
});
it('should return NoopAction when myNotThatAwesomeAction is false', () => {
store.overrideSelector(myAwesomeSelector, false);
myAwesomeEffect$().subscribe(res => {
expect(res).toEqual(NoopAction());
done();
});
});
But what about the first example.
it('should return myNotThatAwesomeAction when myAwesomeValue is true', done => {
store.overrideSelector(myAwesomeSelector, true);
myAwesomeEffect$().subscribe(res => {
expect(res).toEqual(myNotThatAwesomeAction());
done();
});
});
it('should not return myNotThatAwesomeAction when myNotThatAwesomeAction is false', done => {
store.overrideSelector(myAwesomeSelector, false);
// This won't work since the effect won't return anything
myAwesomeEffect$().subscribe(res => {
expect(res).not.toEqual(myNotThatAwesomeAction());
done();
});
});
What should I replace the second test case with? (while not using third party libs)
Update:
To test an effect which contains filter operator I choose this way:
it('myAwesomeEffect$ does not return anything when myAwesomeValue is false', done => {
myEffects.myAwesomeEffect$.subscribe(
() => done.fail(),
() => done.fail(),
() => {
expect(true).toBeTruthy();
done();
}
);
});
So if it throws, error or if it produces value we fail the test.
Using the filter operator to "stop" the effect stream is valid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With