Objective: I'd like to write a proper unit test for a basic NgRx Effect. So far, none of my attempts haven't been successful when using jasmine-marbles.
Here is the effect i'm trying to test:
markMovieAsFinished$ = createEffect(() =>
this.actions$.pipe(
ofType(MovieActions.markMovieAsFinished),
switchMap((action: Action) => {
return this.http.put(`/api/reading-list/${action.item.movieId}/finished`, { finishedDate: action.item.finishedDate })
.pipe(
switchMap(() => EMPTY) // With an optimistic update, we initially handle the 'markMovieAsFinished' action directly in the reducer, hence, no need to dispatch another action on a successful PUT request!
);
})
)
);
And here is my latest attempt using marble testing. (i'm very new at implementing marble testing!):
describe('MovieEffects', () => {
let actions$: Actions;
let effects: MovieEffects;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ NxModule.forRoot(), SharedTestingModule ],
providers: [
MovieEffects,
DataPersistence,
provideMockActions(() => actions$)
]
});
actions$ = TestBed.inject(Actions);
effects = TestBed.inject(MovieEffects);
httpMock = TestBed.inject(HttpTestingController);
});
describe('markMovieAsFinished$', () => {
it('should return an EMPTY observable with the outcome, on success', () => {
const action: Action = MovieActions.markMovieAsFinished({ finishedDate: '1/1/20'});
const completion = EMPTY;
// setup the Effect
actions$ = hot('-a', { a: action });
const response = cold('-b|', { b: {} }); // payload from successful response can just be an empty object
const expected = cold('--c', { c: completion });
expect(effects.markMovieAsFinished$).to.be.eql(expected);
})
});
When I try the above attempt, the markMovieAsFinished$ value returns an empty array. In the above code, I've setup the arrange and assert parts of the unit test.The part I'm not understanding is how to mock a successful PUT Request to test this effect.