React Testing Library报错:Cannot read property 'contents' of undefined——Redux取值问题与测试用例编写求助
解决React Testing Library测试Redux容器组件的报错与渲染验证问题
首先来说你遇到的Cannot read property 'contents' of undefined错误——问题出在你的mock store结构写错了!
看一下你的mapStateToProps:
const mapStateToProps = (state) => { return { graphicalData: state.design.contents ? state.design.contents.graphicalData : {}, }; };
这里是直接从state根节点取design,但你mock的store却多包了一层state,同时还把graphicalData写成了graphicalModel,两层错误叠加,导致state.design变成undefined,自然访问contents就报错了。
第一步:修正Mock Store
把多余的state嵌套去掉,同时把graphicalModel改成graphicalData,完全匹配mapStateToProps的取值路径:
const store = mockStore({ design: { contents: { graphicalData: { cars: [{},{}], bikes: [{},{}] }, }, }, });
第二步:优化测试用例写法
你用了React Testing Library,就别再用ReactDOM.render和手动unmount了——RTL的render方法已经帮你处理了挂载和自动清理(v10+版本默认启用cleanup,afterEach(cleanup)可以删掉)。另外,shallow是Enzyme的API,和RTL的测试理念冲突,建议直接移除。
完整测试用例示例
假设你的组件会根据graphicalData.cars渲染列表项(比如给每个car元素加data-testid="car-item"),下面是符合RTL最佳实践的测试代码:
import React from 'react'; import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/react'; import MyContainer from '../../MyContainer'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; const mockStore = configureMockStore(); // 测试组件正常加载不崩溃 it('renders without crashing', () => { const store = mockStore({ design: { contents: { graphicalData: {} }, }, }); render( <Provider store={store}> <MyContainer /> </Provider> ); // 可选:加一个基础断言确认组件渲染成功 expect(screen.getByRole('generic')).toBeInTheDocument(); }); // 测试cars数组有内容时渲染对应元素 it('displays car items when cars array is not empty', () => { const mockCars = [{ id: 1 }, { id: 2 }]; const store = mockStore({ design: { contents: { graphicalData: { cars: mockCars, bikes: [] }, }, }, }); render( <Provider store={store}> <MyContainer /> </Provider> ); // 获取所有car元素并验证数量 const carItems = screen.getAllByTestId('car-item'); expect(carItems).toHaveLength(mockCars.length); // 如果组件里渲染了具体文本,还可以验证内容 expect(carItems[0]).toHaveTextContent('Car 1'); });
几个关键注意点
- Mock Store结构要和真实Store完全匹配:你的
mapStateToProps从哪里取值,mock就给对应路径的结构,不要多嵌套或少嵌套。 - 遵循RTL的"用户视角"测试理念:用
screen查询元素,优先用getByRole、getByText等贴近用户操作的查询方法,必要时用data-testid标记测试元素。 - 不要混用不同测试库的API:RTL和Enzyme的设计理念不同,选一个坚持用,避免混乱。
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

