如何在TypeScript环境配置React-Testing-Library适配Redux-RTK
问题定位与修复方案
1. 补全testing-utils.ts的TS类型与store结构
你在转TSX时没有给自定义render函数加类型,且要保证测试用的store reducer结构和项目全局store完全一致,否则useAppSelector无法正确读取state:
// testing-utils.ts import React, { ReactElement } from 'react' import { render as rtlRender, RenderOptions } from '@testing-library/react' import { configureStore, PreloadedState } from '@reduxjs/toolkit' import { Provider } from 'react-redux' // 导入项目所有reducer,和全局store结构保持完全一致 import alertReducer from '../alertSlice' // 其他业务reducer也需全部导入 // import userReducer from '../userSlice' import type { RootState } from '../store' // 导入项目全局store定义的RootState类型 // 自定义render函数参数类型 interface CustomRenderOptions extends Omit<RenderOptions, 'wrapper'> { preloadedState?: PreloadedState<RootState> store?: ReturnType<typeof configureStore<RootState>> } function render( ui: ReactElement, { preloadedState, store = configureStore({ reducer: { alert: alertReducer, // 其他reducer按全局结构补全 // user: userReducer }, preloadedState, }), ...renderOptions }: CustomRenderOptions = {} ) { function Wrapper({ children }: { children: React.ReactNode }) { return <Provider store={store}>{children}</Provider> } return rtlRender(ui, { wrapper: Wrapper, ...renderOptions }) } export * from '@testing-library/react' export { render }
2. 修正测试用例的错误写法
你原有测试用例存在三个明显错误:未渲染被测组件、未正确初始化userEvent、点击事件未加await:
import { render, screen } from "../../../testing-utils/test-utils"; import userEvent from '@testing-library/user-event' import SelectMedia from './SelectMedia' // 导入被测组件 test.only("when the user clicks the 'click me' button, a snackbar appears", async () => { const user = userEvent.setup() // @testing-library/user-event v14+ 必须先调用setup初始化 render(<SelectMedia />) // 必须先渲染被测组件 // 初始状态下alert为空,不存在header文本,原有断言逻辑错误 expect(screen.queryByText(/header/i)).not.toBeInTheDocument(); const clickMeButton = screen.getByRole("button", { name: /click me/i }); await user.click(clickMeButton); // 点击是异步操作,必须加await等待事件执行完成 expect( await screen.findByText(/great job header/i) ).toBeInTheDocument(); });
3. 修正alertSlice的初始状态
你渲染出现undefined header,说明alertState初始值不是falsy值(如空对象),导致alertState && alertState.message + " header"的逻辑判断失效,拼接出undefined:
// alertSlice.ts import { createSlice, PayloadAction } from '@reduxjs/toolkit' interface AlertState { type: 'success' | 'error' message: string display: string } // 初始值设为null,而非空对象 const initialState: AlertState | null = null const alertSlice = createSlice({ name: 'alert', initialState, reducers: { setAlert: (state, action: PayloadAction<AlertState>) => { return action.payload }, clearAlert: () => null } }) export const { setAlert, clearAlert } = alertSlice.actions export default alertSlice.reducer
4. 校验selector逻辑
确认你的selectAlert选择器是从正确的根state字段取值:
export const selectAlert = (state: RootState) => state.alert
内容的提问来源于stack exchange,提问作者kevin
相关产品推荐
相关产品推荐

