Blog>
Snippets

Testing Reducers with Typed Actions

Showcase how to write unit tests for reducers using typed actions to verify that the reducers correctly handle various action types and prevent type errors in the Redux store.
import { createStore } from 'redux';
import { expect } from 'chai';

// Action types
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

// Typed actions
interface IncrementAction {
  type: typeof INCREMENT;
}

interface DecrementAction {
  type: typeof DECREMENT;
}

type CounterAction = IncrementAction | DecrementAction;

// Action creators
function increment(): IncrementAction {
  return { type: INCREMENT };
}

function decrement(): DecrementAction {
  return { type: DECREMENT };
}

// Reducer
function counterReducer(state: number = 0, action: CounterAction): number {
  switch (action.type) {
    case INCREMENT:
      return state + 1;
    case DECREMENT:
      return state - 1;
    default:
      return state;
  }
}

// Testing the reducer
describe('counterReducer', () => {
  it('should increment the state by 1', () => {
    const initialState = 0;
    const state = counterReducer(initialState, increment());
    expect(state).to.equal(1);
  });

  it('should decrement the state by 1', () => {
    const initialState = 1;
    const state = counterReducer(initialState, decrement());
    expect(state).to.equal(0);
  });

  it('should not affect state for unknown action', () => {
    const initialState = 2;
    const state = counterReducer(initialState, { type: 'UNKNOWN_ACTION' } as CounterAction);
    expect(state).to.equal(2);
  });
});
This code defines action types, typed actions, action creators, a reducer, and unit tests for the reducer. The reducer handles increment and decrement actions. The tests verify the behavior of the reducer using typed actions to ensure type safety. Chai's expect method is used for assertions in the tests.