Я хочу создать пару тестов для своих компонентов, но так как я использую 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()
})
})
🤔 А знаете ли вы, что...
React использует компонентную архитектуру для организации кода.
Это исправить
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 }) };
}