I would like to test the following epic:
authEpics.logoutEpic = function (action$, _, deps) {
return action$.pipe(
ofType(authActions.logout),
tap(() => {
const { history, browser } = deps;
browser.localStorage.removeItem('user');
history.push(ROUTES.LOGIN);
}),
ignoreElements()
);
};
Here's the test case:
describe('Logout Epic', () => {
test('should remove user from localStorage', (done) => {
scheduler.run((helpers) => {
const { hot, expectObservable } = helpers;
const action$ = hot('a', {
a: authActions.logout(),
});
const deps = testUtils.mockEpicDependencies();
const output$ = authEpics.logoutEpic(action$, null, deps);
// Statement 1.
expectObservable(output$).toBe('');
// Statement 2.
output$.subscribe({
complete: () => {
expect(deps.browser.localStorage.removeItem).toHaveBeenCalledWith('user');
expect(deps.history.push).toHaveBeenCalledWith(ROUTES.LOGIN);
done();
}
});
});
});
Based on the definition of ignoreElements, I am not able grok the following observations:
expectObservable(output$).toBe('|')
should work, but it didn't. Instead expectObservable(output$).toBe('')
works.complete
function never gets called.To make the test case work, I had to flush the promise queue (and not use expectObservable
). Here's the revised test case:
describe('Logout Epic', () => {
test('should remove user from localStorage', (done) => {
scheduler.run(async (helpers) => {
const { hot } = helpers;
const action$ = hot('a', {
a: authActions.logout(),
});
const deps = testUtils.mockEpicDependencies();
const output$ = authEpics.logoutEpic(action$, null, deps);
// *** Flush the promise queue ***
await new Promise((resolve) => resolve());
expect(deps.browser.localStorage.removeItem).toHaveBeenCalledWith('user');
expect(deps.history.push).toHaveBeenCalledWith(ROUTES.LOGIN);
done();
});
});