Если вы читаете это, я предполагаю, что вы тестируете приложение Redux с Библиотекой тестирования. И вы, вероятно, захотите, чтобы некоторые тесты запускались с хранилищем Redux в определенном состоянии в качестве начальных условий тестирования.

Как вы, наверное, знаете, Testing Library делает упор на« поведение тестирования (тесты, которые взаимодействуют с вашим приложением так же, как пользователи). Сторонники поведенческого тестирования сказали бы: чтобы настроить хранилище Redux с определенными значениями, запустите тест, запустив действия пользователя, которые заполняют состояние.

Однако это просто нецелесообразно делать для каждого теста, особенно если желаемое состояние требует большого количества взаимодействий (и, возможно, значений сервера) для настройки. В этом сообщении блога подробно рассказывается, как настроить фабрику хранилищ для создания тестового хранилища (с начальными значениями) для настройки тестирования.

Создание фабрики магазина

Идея здесь в том, что у вас есть «фабричная функция» для создания нового магазина. Эта функция создает хранилище для производственных и тестов , чтобы убедиться, что ваши тесты как можно ближе к производственному коду.

Примеры

Вот пример функции фабрики магазина с использованием Redux Toolkit и Redux Saga:

Вот еще один, использующий Redux и Redux Thunk:

Обе эти фабрики хранилищ имеют функцию createStoreWithMiddlewares, которая принимает initialState и может использоваться для создания производственного или тестового хранилища - с одинаковой конфигурацией. Вы можете использовать эти примеры, чтобы написать createStoreWithMiddlewares для своего приложения.

Использование фабрики магазина: производство

Производственный магазин может быть создан с использованием createStoreWithMiddlewares либо в вашем файле store / index.js, либо в src / index.js, и добавлен в качестве атрибута store в Redux Provider .

очень важно добавить поставщика Redux в src / index.js, а не в App.js! Если App.js содержит Redux Provider с производственным хранилищем, вы не сможете протестировать компонент App с помощью тестового хранилища, поскольку фактическое производственное хранилище будет использоваться при рендеринге <App />.

Использование фабрики магазина: тесты

Теперь, когда рабочий Redux Provider был передан в index.js, у нас есть полный контроль над хранилищем для наших тестов. Следуйте этим шагам и наслаждайтесь мощью!

Шаг 1. Создайте пользовательскую функцию рендеринга

Мы можем перезаписать функцию библиотеки тестирования render настраиваемым рендером, который включает Redux Provider с частным хранилищем только для этого теста. Напишите этот код, скажем, в src / test-utils / index.tsx (фактическое расположение и имя файла не важны. Кроме того, если вы не используете Typescript, вы, вероятно, захотите использовать index.jsx вместо index.tsx).

(этот код адаптирован из Redux Testing Docs). Обратите внимание, что Typescript для Redux-Toolkit отличается от обычного Redux; используйте строки, относящиеся к вашему проекту (или не используйте машинописный текст вообще, если это ваша проблема).

Идея с приведенным выше кодом:

  • Пользовательский рендеринг в этом документе использует preloadedState и компонент пользовательского интерфейса.
  • Пользовательский рендеринг оборачивает компонент пользовательского интерфейса в Redux Provider с хранилищем, содержащим preloadedState.
  • Код экспортирует все из @ testing-library / react, а затем переопределяет метод render, поэтому этот файл можно использовать вместо фактической @ testing-library / response (как мы увидим, когда будем его использовать).
  • При импорте из этого файла вместо @ testing-library / response все методы, кроме render (например, screen или fireEvent), будут поступать прямо из @ testing-library / response - кроме render, который был заменен нашим кастомным render.

Обратите внимание, что вы можете создать хранилище заранее и передать его функции render, или вы можете использовать значение по умолчанию, которое создает новое хранилище с вашим preloadedState, используя всю конфигурацию из функции configureStoreWithMiddlewares, которую использует наша продукция:

store = configureStoreWithMiddlewares(preloadedState),

Если вы действительно создаете хранилище и передаете его в качестве аргумента, очень важно, чтобы новое хранилище создавалось для каждого теста (чтобы не было разделения состояния между тестами).

Шаг 2. Использование пользовательского рендеринга в тестах

Чтобы использовать этот пользовательский рендеринг в тесте, мы импортируем его из нашего файла test-utils / index.tsx, а не из @ testing-library / response.

Допустим, у вас есть страница профиля пользователя, которая выглядит так:

Компонент UserProfile может выглядеть примерно так:

Вы можете видеть, что часть состояния user имеет свойства name и email. Чтобы проверить, что пользователь name и email отображается на странице профиля, вам необходимо предварительно загрузить в состояние пользовательский объект для теста.

Вот как могут выглядеть тесты с нашим пользовательским render методом:

Вот шаги в пользовательском методе render, которые заставят это работать:

  1. Пользовательский метод render использует параметр preloadedState (и функцию createStoreWithMiddlewares, используемую в производстве) для создания нового магазина.
  2. Затем пользовательский метод render создает оболочку с поставщиком Redux, передавая хранилище с предварительно загруженным состоянием в качестве опоры.
  3. Пользовательский метод render использует фактическую библиотеку тестирования / response render для визуализации аргумента ui (в данном случае <UserProfile />), заключенного во вновь созданный поставщик из шага 2, и возвращает результат.

Этот результат теперь имеет хранилище, предварительно заполненное указанным пользователем, вызов useSelector в компоненте возвращает fakeUser, и тесты проходят.

Больше контента на plainenglish.io