Integration Testing of Redux Store with TypeScript
Provide an example of how to write integration tests for a Redux store using TypeScript, ensuring the correct behavior of actions and reducers.
import { createStore, applyMiddleware, Store } from 'redux';
import thunk from 'redux-thunk';
import { rootReducer, AppState } from './store'; // Import your rootReducer and AppState
// Define a type for the dispatch
export type AppDispatch = typeof store.dispatch;
// Creating a function to easily create a configured store for tests
export function configureTestStore(): Store<AppState> {
const store = createStore(rootReducer, applyMiddleware(thunk));
return store;
}
This piece of code imports the necessary Redux modules to create a test store using the rootReducer and thunk middleware. This test store can mimic the actual store's behavior in a testing environment.
import { configureTestStore } from './testUtils';
import * as actions from './actions';
import { AnyAction } from 'redux';
// Define your specific action creators and initial state
// Example action creator
const addTodo = (title: string) => ({
type: 'ADD_TODO',
payload: { title }
});
// Define the initial state type
interface TodoState {
todos: { title: string }[];
}
// Integration test example
it('should handle adding a todo', () => {
const store = configureTestStore();
const initialState: TodoState = { todos: [] };
// Dispatch the action
store.dispatch(addTodo('Test Todo') as AnyAction);
// Get the current state
const currentState = store.getState();
// Assert that the state was updated correctly
expect(currentState.todos).toEqual([{ title: 'Test Todo' }]);
});
Here we have an integration test example using Jest. It tests that when the 'addTodo' action creator is dispatched, the new todo item is correctly added to the state.
import { Action, combineReducers, Reducer } from 'redux';
// Example todo reducer
interface TodoState {
todos: { title: string }[];
}
const INITIAL_STATE: TodoState = { todos: [] };
function todoReducer(state = INITIAL_STATE, action: Action): TodoState {
switch (action.type) {
case 'ADD_TODO':
return {
...state,
todos: [...state.todos, action.payload],
};
default:
return state;
}
}
// Combine with other reducers as needed
export const rootReducer: Reducer = combineReducers({
todo: todoReducer,
// ... other reducers here
});
This code defines a sample todoReducer and the rootReducer. The todoReducer handles adding a todo to the state when receiving the 'ADD_TODO' action type. The rootReducer uses Redux's combineReducers to combine multiple reducers.