Протестируйте компонент redux-toolkit с неудачным пользовательским рендерингом с поставщиками

Я хочу создать пару тестов для своих компонентов, но так как я использую Redux, мне нужно отправить провайдера, согласно документации мне нужно сделать что-то вроде renderWithProviders, чтобы я мог повторно использовать его для разных компонентов и вот что Я пытаюсь это сделать, я использую Vite и TypeScript для этого проекта, но получаю следующие ошибки и не знаю, как это исправить.

Это пользовательский рендеринг, который я пытаюсь создать:

import React, { PropsWithChildren } from 'react'
import { render } from '@testing-library/react'
import { configureStore } from '@reduxjs/toolkit'
import { Provider } from 'react-redux'

import favsReducer from '../../store/favs/slice'

export function renderWithProviders(
  ui: React.ReactElement,
  {
    preloadedState = {},
    // Automatically create a store instance if no store was passed in
    store = configureStore({
      reducer: { favs: favsReducer },
      preloadedState,
    }),
    ...renderOptions
  } = {}
) {
  function Wrapper({ children }: PropsWithChildren) {
    return <Provider store = {store}>{children}</Provider>;
  }

  // Return an object with the store and all of RTL's query functions
  return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
}

Мой магазин такой:

import { Middleware, configureStore } from "@reduxjs/toolkit"
import favsReducer from './favs/slice'

const persistanceLocalStorageMiddleware: Middleware = (store) => (next) => (action) => {
  next(action);
  localStorage.setItem('__favorite__redux__state__', JSON.stringify(store.getState()));
};

export const store = configureStore({
  reducer: {
    favs: favsReducer
  },
  middleware: (getDefaultMiddleware) => {
    return getDefaultMiddleware().concat(persistanceLocalStorageMiddleware)
  }
})

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

и кусочек для фаворитов вот этот:

import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { Favorite, Id, FavoriteWithId } from "../../interfaces/FavoritesInterface"

const DEFAULT_STATE: FavoriteWithId[] = []

const initialState: FavoriteWithId[] = (() => {
  const persistedState = localStorage.getItem('__favorite__redux__state__')
  if (persistedState) return JSON.parse(persistedState).favs
  return DEFAULT_STATE
})()

export const favsSlice = createSlice({
  name: 'favs',
  initialState: initialState,
  reducers: {
    addNewFavorite: (state, action: PayloadAction<Favorite>) => {
      const id = crypto.randomUUID();
      return [...state, { id, ...action.payload }]
    },
    deleteFavoriteById: (state, action: PayloadAction<Id>) => {
      const id = action.payload;
      return state.filter((fav) => fav.id !== id)
    }
  }
})

export default favsSlice.reducer
export const { addNewFavorite, deleteFavoriteById } = favsSlice.actions

Итак, я не знаю, почему я получаю сообщение

'favs' не существует в типе 'Reducer<{ favs: FavoriteWithId[]; }, UnknownAction, любое>'

Я думал, что редуктор в тестах должен иметь свойство «favs», как и в магазине, который я настраиваю, но я больше не уверен, может ли кто-нибудь дать мне подсказку или что-то в этом роде, как действовать дальше?

Модульный тест, который я пытаюсь написать, следующий:

import '@testing-library/jest-dom/jest-globals'
import '@testing-library/jest-dom'
import { screen } from '@testing-library/react'
import DogCard from '../components/profile-card/DogCard'
import { renderWithProviders } from './utils/test-utils'

describe('DogCard component', () => {
  test('renders the DogCard component', () => {
    renderWithProviders(<DogCard />)
    const dogImage = screen.getByTestId('dog-image')
    expect(dogImage).toBeInTheDocument()
  })
})

Вот репозиторий на github

🤔 А знаете ли вы, что...
React использует компонентную архитектуру для организации кода.


140
1

Ответ:

Решено

Это исправить

const preloadedState: FavoriteWithId[] = []

export function renderWithProviders(
  ui: React.ReactElement,
  {
    // Automatically create a store instance if no store was passed in
    store = configureStore({
      reducer: favsReducer,
      preloadedState,
    }),
    ...renderOptions
  } = {}
) {
  function Wrapper({ children }: PropsWithChildren) {
    return <Provider store = {store}>{children}</Provider>;
  }

  // Return an object with the store and all of RTL's query functions
  return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
}

Интересные вопросы для изучения

Как исправить ошибку. Класс расширяет значение, неопределенное не является конструктором или нулевым значениемКак мне заставить этот раздел javascript работатьМаршрутизация страниц Typescript не отображает подстраницу при нажатии (React Router v6)Состояние реакции с элементами JSX устанавливает для последней ссылки в массиве ссылок значение nullКак центрировать модальное окно React Flowbite после изменения размера ширины?Маршрутизация страниц Typescript не отображает подстраницу при нажатии (React Router v6)Как я могу указать рабочему пространству Yarn ссылаться на исполняемые файлы в корне моего монорепозитория JavaScript?INVALID_URL развертывание приложения next.js в статическом веб-приложении Azure во время сборки действий GitHubЕсть ли многоугольная цепочка Amoy для ThirdWeb?Как заставить TypeScript выводить поля объекта в возвращаемом типе кортежа на основе условий?