Blog>
Snippets

Testing a Redux-Saga with Jest

Provide an example of testing a Redux-Saga with Jest, focusing on how to test that a saga dispatches an expected action after performing an async operation.
import { runSaga } from 'redux-saga';
import { call, put } from 'redux-saga/effects';
import * as api from './api'; // Assume this contains the async function callApiFunction
import { fetchDataSuccess, fetchDataFailure } from './actions';

// Our test target saga
function* fetchDataSaga(action) {
  try {
    const data = yield call(api.callApiFunction, action.url);
    yield put(fetchDataSuccess(data));
  } catch (error) {
    yield put(fetchDataFailure(error));
  }
}
This piece of code defines a Redux-Saga generator function named fetchDataSaga. The function attempts to call an asynchronous API function and dispatches either a success or failure action based on the result of that API call.
import { fetchDataSaga } from './sagas';
import { runSaga } from 'redux-saga';
import { fetchDataSuccess, fetchDataFailure } from './actions';

test('fetchDataSaga should dispatch success action on successful API call', async () => {
  const dispatchedActions = [];
  const mockedData = { id: 1, name: 'Test' };
  const fakeStore = {
    dispatch: action => dispatchedActions.push(action),
    getState: () => ({})
  };
  await runSaga(fakeStore, fetchDataSaga, { url: 'test.com' }).toPromise();

  // Mock API call
  api.callApiFunction = jest.fn(() => Promise.resolve(mockedData));

  expect(dispatchedActions).toContainEqual(fetchDataSuccess(mockedData));
});
This Jest test verifies that fetchDataSaga dispatches the expected success action when the API call is successful. It uses Jest to mock the API call, simulating a successful response, and then checks if the correct action has been dispatched.
test('fetchDataSaga should dispatch failure action on failed API call', async () => {
  const dispatchedActions = [];
  const fakeStore = {
    dispatch: action => dispatchedActions.push(action),
    getState: () => ({})
  };
  const error = new Error('API call failed');

  // Mock API call to reject
  api.callApiFunction = jest.fn(() => Promise.reject(error));

  await runSaga(fakeStore, fetchDataSaga, { url: 'test.com' }).toPromise();

  expect(dispatchedActions).toContainEqual(fetchDataFailure(error));
});
This test case verifies that fetchDataSaga dispatches a failure action when the API call fails. It mocks the API call to simulate a failure, then checks that the correct failure action has been dispatched.