Integration Testing with Redux Store
Explain how to perform integration tests on sagas by connecting them with a Redux store and asserting state changes and side effects.
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { put } from 'redux-saga/effects';
import SagaTester from 'redux-saga-tester';
import mySaga from './mySaga'; // assume this saga listens for 'ACTION_REQUEST' and dispatches 'ACTION_SUCCESS'
import rootReducer from './reducers';
Import necessary modules and files like createSagaMiddleware from redux-saga, SagaTester for integration testing, your rootReducer, and the saga you want to test. mySaga and rootReducer are placeholders for whatever your files are named.
function* triggerActionSaga() {
yield put({ type: 'ACTION_REQUEST', payload: { id: 1 } });
}
Define a simple saga that triggers the action your main saga listens for. This is for testing purposes.
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
rootReducer,
applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(mySaga);
Create a Redux store and apply the saga middleware, then run your main saga. This mimics the application's setup.
const initialState = { data: null, loading: false, error: null };
const sagaTester = new SagaTester({
initialState,
reducers: rootReducer
});
sagaTester.start(triggerActionSaga);
Instantiate SagaTester with the initial state of your app and your rootReducer. Start the triggerActionSaga to initiate the ACTION_REQUEST.
sagaTester.dispatch({ type: 'ACTION_REQUEST', payload: { id: 1 } });
sagaTester.waitFor('ACTION_SUCCESS').then(() => {
console.log('Action SUCCESS dispatched!');
const newState = sagaTester.getState();
console.log(newState);
});
Dispatch 'ACTION_REQUEST' to trigger your main saga. Use waitFor to pause until 'ACTION_SUCCESS' is dispatched, then log the new state. This is where you would assert changes in the state against your expectations.