Blog>
Snippets

Testing Saga with Race Effect

Illustrate testing a saga that uses the race effect to handle concurrent tasks, showing how to assert which effect won the race.
import { race, take, put, call } from 'redux-saga/effects';
import { delay } from 'redux-saga';
function* mySaga() {
    yield race({
        task: call(fetchData, 'url'),
        timeout: delay(5000)
    });
}
This function* mySaga demonstrates using the race effect to handle concurrent tasks such as fetching data and a timeout. If fetchData finishes first, 'task' wins the race, otherwise 'timeout' does.
import { expectSaga } from 'redux-saga-test-plan';
import { race, call, delay } from 'redux-saga/effects';
import { fetchData, mySaga } from './sagas';

test('race effect wins with task', () => {
  return expectSaga(mySaga)
    .provide([[call(fetchData, 'url'), true]])
    .put({ type: 'FETCH_SUCCESS' })
    .run();
});
Here we are using expectSaga to test the mySaga function. We mock the fetchData call to resolve immediately, simulating the 'task' winning the race. We then assert that the success action is dispatched as a result.
test('race effect wins with timeout', () => {
  return expectSaga(mySaga)
    .provide([
      [call(fetchData, 'url'), Promise.reject(new Error('timeout'))],
      [delay(5000), null]
    ])
    .not.put({ type: 'FETCH_SUCCESS' })
    .put({ type: 'FETCH_FAILURE' })
    .run();
});
In this test, we're simulating the 'timeout' winning the race by making fetchData reject and ensuring delay resolves. We assert that the success action is not dispatched and instead a failure action is dispatched.