π Π’Π΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ 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