Redux + React Testing Library测试中如何自定义修改store的state?
问题原因排查
你代码里一共3处低级错误,修改后即可实现单测试自定义state注入:
- 测试工具中
configureStore初始化写法错误:configureStore仅接收单个配置对象,初始状态需要通过配置项的preloadedState字段传入,不能直接作为第二个参数传入 - 参数名不匹配:测试文件调用工具函数时传的参数键是
state,但工具函数接收的参数键是initialState,导致自定义状态根本没有被工具函数接收 - 状态结构不符合根state规范:你的slice命名为
coinsAll,rootReducer挂载后这部分状态会嵌套在根state的coinsAll字段下,你传入的状态少了这一层嵌套,结构不匹配
修复后代码
1. 测试工具代码修改
import React from "react"; import { render as rtlRender } from "@testing-library/react"; import { configureStore } from "@reduxjs/toolkit"; import { Provider } from "react-redux"; import reducer from "../../src/redux/rootReducer"; function renderTestComponent( ui, { initialState, // 修正:preloadedState传入初始状态 store = configureStore({ reducer, preloadedState: initialState }), ...renderOptions } = {} ) { function Wrapper({ children }) { return <Provider store={store}>{children}</Provider>; } return rtlRender(ui, { wrapper: Wrapper, ...renderOptions }); } // re-export everything export * from "@testing-library/react"; // override render method export { renderTestComponent };
2. 测试文件代码修改
import React from "react"; import CoinList from "../../components/coinlist/CoinList"; import { screen } from "@testing-library/react"; import { renderTestComponent } from "../testUtil"; describe("CoinList", () => { const initialState = { // 修正:加外层coinsAll字段匹配根state结构 coinsAll: { coinsAll: [], status: "idle", error: null, } }; const renderCoinList = (args, state) => { const defaultProps = {}; const props = { ...defaultProps, ...args }; // 修正:传参键名改为initialState和工具函数匹配 return renderTestComponent(<CoinList {...props} />, { initialState: state }); }; test("renders spinner", () => { renderCoinList(null, initialState); expect(screen.getByAltText(/Loading/i)).toBeInTheDocument(); }); test("renders coin list", () => { renderCoinList(null, { // 修正:加外层coinsAll字段匹配根state结构 coinsAll: { coinsAll: [ { id: "ethereum", name: "Ethereum", current_price: "4500" }, { id: "bitcoin", name: "BTC", current_price: "100,000" }, ], status: "succeeded", error: null, } }); expect(screen.getByText(/Ethereum/i)).toBeInTheDocument(); expect(screen.getByText(/BTC/i)).toBeInTheDocument(); }); });
内容的提问来源于stack exchange,提问作者tjacqu2
相关产品推荐
相关产品推荐

