Я помню, как впервые слово «реагировать на крючок» шептали вверх и вниз по стенам с кофе на моей первой работе в области разработки.
Я вернулся к своему столу после того, как впервые услышал о них, быстро открыл YouTube, чтобы посмотреть несколько видеороликов, объясняющих концепцию, но я не могу сказать, что концепция прижилась, поэтому я продолжал надеяться, что никто не попросит меня объяснить их подробно или боже. запрети, напиши кастомный хук (жуткий) 👻
но теперь, когда я комфортно работаю с различными реактивными хуками в течение последних нескольких лет, я, наконец, понимаю силу и продуктивное преимущество, которые держат реагирующие крючки (наконец-то круто, ура)
Итак, как, черт возьми, мы тестируем пользовательские хуки?
я предполагаю, что если вы зашли так далеко, вы знаете основы хуков, но даже тогда они не так важны для примера — концепция тестирования достаточно очевидна
в примере мы визуализируем наш хук в контексте фиктивного хранилища избыточности (‹Provider›), поскольку наш хук использует селектор из хранилища избыточности.
решение, которое я использовал (на которое сильно повлияли другие утилиты, с которыми я работал раньше), состоит в том, чтобы объединить мощь react-hook-testing-library и redux-mock-store для создания повторно используемого хук тестирования, который отображает хук (недотестированный) и позволяет вам тестировать любые результаты хука (в примере,
Затем я добавил некоторую фиктивную поддержку, когда хуки полагаются на селекторы (react-redux) или состояние redux (ну, в конечном счете, все, что нужно вашему компоненту, например контекст или перевод? решать вам!)
import React, {PropsWithChildren} from 'react'; import configureMockStore from 'redux-mock-store'; import {Provider} from 'react-redux'; import {renderHook} from '@testing-library/react-hooks'; import {Store} from 'redux'; import {mockStore} from '.'; const mockStore = configureMockStore(...); const wrapInMockProvider = (mockStore: Store) => ({children}: PropsWithChildren) => ( <Provider store={mockStore}> {children} </Provider> ); export function renderReduxHook<HookResultType>( callback, initialState = {} ): HookResultType { const _mockStore = mockStore(initialState); const {result} = renderHook(callback, { wrapper : wrapInMockProvider(_mockStore) }); // result is a ref, just unwrapping for convenience return result.current as HookResultType; }; ... // useHookUnderTest.ts export const useHookUnderTest = (value: number) => { const reduxValue = useSelector({value: 2}); const getValue = () => { return value + reduxValue; } return { getValue, reduxValue } } ... // useHookUnderTest.test.ts import {renderReduxHook} from './test-utils'; import useHookUnderTest from './useHookUnderTest; describe('componentTestFile', () => { const initialMockState = {value: 10}; const {reduxValue, getValue} = renderReduxHook<HookUnderTestResultType>(() => hookUnderTest(), initialMockState); describe('getValue', () => { test('should add the redux value to the given value', () => { expect(getValue(1)).toEqual(11); expect(getValue(2)).toEqual(12); expect(getValue(3)).toEqual(13); }); }); });
я основывал свое решение на нескольких разных сообщениях, но в основном нашел эту документацию полезной для отправки в обертке
вы можете видеть, что мы просто издеваемся над провайдером для фиктивного хранилища, чтобы можно было манипулировать любыми перехватчиками избыточных значений для тестирования, что можно полностью использовать теперь, когда у вас есть возможность работать с react-hooks-testing-library. , поэтому, чтобы углубить свои навыки тестирования, погрузитесь в их библиотеку и документацию, чтобы найти еще больше идей для тестирования.
теперь удачи в тестировании вашего нового тестового хука, я позволю вам сделать эту часть!
хотелось бы услышать, как другие проверяют свои крючки (если вообще? 👀)!