Я помню, как впервые слово «реагировать на крючок» шептали вверх и вниз по стенам с кофе на моей первой работе в области разработки.

Я вернулся к своему столу после того, как впервые услышал о них, быстро открыл 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. , поэтому, чтобы углубить свои навыки тестирования, погрузитесь в их библиотеку и документацию, чтобы найти еще больше идей для тестирования.

теперь удачи в тестировании вашего нового тестового хука, я позволю вам сделать эту часть!

хотелось бы услышать, как другие проверяют свои крючки (если вообще? 👀)!