🚀 Тестирование Redux: Actions, Reducers и подключение mock-хранилища
Привет! Сегодня разберём, как правильно тестировать
actions,
reducers и компоненты, подключённые к Redux. Эти знания помогут вам убедиться, что ваше состояние и логика работают корректно.
🔹 Тестирование reducers
Reducer — это чистая функция. Она принимает текущее состояние и action, возвращая новое состояние.
Структура теста
1. Определите начальное состояние.
2. Передайте в reducer action и проверьте результат.
Пример:
import { counterReducer } from './counterSlice';
describe('counterReducer', () => {
it('должен увеличивать значение', () => {
const initialState = { count: 0 };
const action = { type: 'counter/increment' };
const result = counterReducer(initialState, action);
expect(result).toEqual({ count: 1 });
});
it('должен уменьшать значение', () => {
const initialState = { count: 2 };
const action = { type: 'counter/decrement' };
const result = counterReducer(initialState, action);
expect(result).toEqual({ count: 1 });
});
});
Почему это важно?
- Убедитесь, что ваш reducer возвращает корректное состояние для каждого action.
- Проверка edge-кейсов (например, неожиданных значений).
🔹 Тестирование actions
Actions сами по себе тестировать несложно. Однако для
thunk или асинхронных actions вам понадобятся моки.
Пример: Тестирование синхронных actions
import { increment, decrement } from './counterSlice';
describe('actions', () => {
it('increment должен возвращать правильный action', () => {
expect(increment()).toEqual({ type: 'counter/increment' });
});
it('decrement должен возвращать правильный action', () => {
expect(decrement()).toEqual({ type: 'counter/decrement' });
});
});
Пример: Тестирование асинхронных actions (с помощью
redux-thunk
)
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { fetchData } from './dataActions';
import { fetchDataSuccess } from './dataSlice';
const mockStore = configureMockStore([thunk]);
describe('async actions', () => {
it('должен диспатчить fetchDataSuccess после успешного API-запроса', async () => {
const store = mockStore({});
const mockResponse = { data: 'test' };
// Мокаем fetch
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve(mockResponse),
})
);
await store.dispatch(fetchData());
const actions = store.getActions();
expect(actions[0]).toEqual(fetchDataSuccess(mockResponse));
});
});
🔹 Подключение mock-хранилища для компонентов
Для тестирования компонентов, использующих Redux, используйте
mock-store или обёртку
Provider
с тестовым хранилищем.
Пример: Тестирование компонента с
Provider
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import Counter from './Counter';
const mockStore = configureMockStore([]);
describe('Counter component', () => {
it('должен отображать начальное значение', () => {
const store = mockStore({ counter: { count: 0 } });
const { getByText } = render(
<Provider store={store}>
<Counter />
</Provider>
);
expect(getByText('Count: 0')).toBeInTheDocument();
});
});
🔹 Практические советы
1.
Тестируйте reducers отдельно: Это чистые функции, их тестировать проще всего.
2.
Используйте моки для API-запросов: jest.fn()
или библиотеки, такие как
msw.
3.
Тестируйте взаимодействие компонентов с Redux: С помощью mock-store или настоящего Redux-хранилища в тестовой среде.
🎯 Заключение
Тестирование Redux — важная часть создания стабильных и надёжных приложений. Начните с проверки reducers, затем переходите к actions, а после - к тестированию компонентов с использованием mock-хранилища.
ReactJs Daily | #testing