Blog>
Snippets

Step-by-Step Saga Test with Jest

Showcase testing a Redux Saga step-by-step using Jest by checking the sequence of yielded effects and mocking responses for asynchronous calls.
import { call, put } from 'redux-saga/effects';
import { fetchUserData, loadUserSuccess, loadUserFailure } from './actions';
import { getUserData } from './api';
import { testSaga } from 'redux-saga-test-plan';
First, import necessary effects from redux-saga, actions from your actions file, the API call from your services/api file, and testSaga from redux-saga-test-plan for testing.
describe('fetchUserData Saga', () => {
  it('should handle successfully fetching user data', () => {
    const userId = '123';
    const user = { id: userId, name: 'John Doe' };

    testSaga(fetchUserData, userId)
      .next()
      .call(getUserData, userId)
      .next(user)
      .put(loadUserSuccess(user))
      .next()
      .isDone();
  });
});
Create a describe block for your saga tests. Inside, write an it block for a success scenario. Use testSaga to test the saga step-by-step. Use .next() to simulate advancing the generator, .call() to assert the saga makes the expected call, .put() to assert the expected action is dispatched, and .isDone() to assert the saga completes.
it('should handle errors when fetching user data fails', () => {
  const userId = '123';
  const error = new Error('An error occurred');

  testSaga(fetchUserData, userId)
    .next()
    .call(getUserData, userId)
    .throw(error)
    .put(loadUserFailure(error))
    .next()
    .isDone();
});
Write another it block for error handling scenario. Simulate the API call throwing an error and the saga dispatching a failure action accordingly.