Testing a Saga with redux-saga-test-plan
Showcase testing a saga by using redux-saga-test-plan library to simulate actions and asserting the effects saga yields.
import { call, put } from 'redux-saga/effects';
import { expectSaga } from 'redux-saga-test-plan';
import { fetchUser } from './api';
import { REQUEST_USER, RECEIVE_USER } from './actions';
// Saga to be testedunction* fetchUserSaga(action) {
try {
const user = yield call(fetchUser, action.payload);
yield put({ type: RECEIVE_USER, user });
} catch (e) {
// handle the error within your saga
}
}
Defines a simple saga for fetching a user which will be the subject of our test.
import { throwError } from 'redux-saga-test-plan/providers';
it('successfully fetches a user', () => {
const fakeUser = { name: 'John Doe' };
const userId = 1;
return expectSaga(fetchUserSaga, { type: REQUEST_USER, payload: userId })
// Simulate the API call to return `fakeUser`
.provide([[call(fetchUser, userId), fakeUser]])
// Assert that the saga will eventually put a RECEIVE_USER action
.put({ type: RECEIVE_USER, user: fakeUser })
// Start the test and return the Promise
.run();
});
Tests the saga to verify it fetches a user correctly by simulating the API call and asserting the output.
it('handles the fetch error', () => {
const userId = 1;
const error = new Error('An error occurred');
return expectSaga(fetchUserSaga, { type: REQUEST_USER, payload: userId })
// Simulate an error response from the API call
.provide([
[call(fetchUser, userId), throwError(error)]
])
// Assert that no RECEIVE_USER action is put due to the error
// In a real-world scenario, you might check for a specific failure action instead
// .put({type: 'FETCH_FAILED', error})
.run();
});
Tests error handling within the saga by simulating an error in the API call.