如何用React Testing Library为Recharts柱状图组件编写单元测试
React Recharts 柱状图组件单元测试解决方案
你的测试失败核心原因是Recharts 渲染的是 SVG 元素,而非普通 HTML 文本节点,直接用screen.getByText无法匹配到 SVG 中的文本;另外ResponsiveContainer在测试环境中没有默认宽高,可能导致组件渲染异常。以下是具体解决方法:
步骤1:给测试环境提供固定宽高容器
ResponsiveContainer依赖父容器尺寸,测试时手动包裹一个带明确宽高的 div:
render( <div style={{ width: '800px', height: '300px' }}> <BarChart data={chartData} /> </div> );
步骤2:正确查询 SVG 中的文本内容
SVG 文本节点需要通过特定方式匹配,推荐两种方案:
方案一:用getByText匹配 SVG 文本
直接使用文本内容匹配,配合exact选项兼容可能的文本渲染差异:
// 验证X轴月份标签 expect(screen.getByText('Jan 2022')).toBeInTheDocument(); expect(screen.getByText('Feb 2022')).toBeInTheDocument(); // 验证Y轴数值标签 expect(screen.getByText('10')).toBeInTheDocument(); expect(screen.getByText('20')).toBeInTheDocument();
方案二:通过data-testid定位组件
给柱状图元素添加data-testid属性,方便精准定位:
首先修改组件代码:
<Bar dataKey='count' fill={color} barSize={barSize} data-testid="bar-chart-bar" />
然后在测试中查询:
// 验证柱状图数量与数据条数一致 const bars = screen.getAllByTestId('bar-chart-bar'); expect(bars).toHaveLength(chartData.length);
步骤3:测试自定义属性生效情况
针对组件的可配置项编写测试,比如颜色、Y轴小数开关等:
test('自定义颜色正确应用到柱状图', () => { render( <div style={{ width: '800px', height: '300px' }}> <BarChart data={chartData} color="#ff4444" /> </div> ); const bars = screen.getAllByTestId('bar-chart-bar'); bars.forEach(bar => { expect(bar).toHaveStyle('fill: #ff4444'); }); }); test('默认配置下Y轴不显示小数', () => { render( <div style={{ width: '800px', height: '300px' }}> <BarChart data={chartData} /> </div> ); // 检查是否没有带小数点的文本 expect(screen.queryByText(/\./)).not.toBeInTheDocument(); });
完整测试代码示例
import { render, screen } from '@testing-library/react'; import { MonthlyApplication } from 'store/stats/types/stats-state.types'; import BarChart from '../bar-chart/bar-chart.component'; const chartData: MonthlyApplication[] = [ { month: 'Jan 2022', count: 10 }, { month: 'Feb 2022', count: 20 }, ]; test('渲染柱状图并显示正确的标签', () => { render( <div style={{ width: '800px', height: '300px' }}> <BarChart data={chartData} /> </div> ); expect(screen.getByText('Jan 2022')).toBeInTheDocument(); expect(screen.getByText('Feb 2022')).toBeInTheDocument(); expect(screen.getByText('10')).toBeInTheDocument(); expect(screen.getByText('20')).toBeInTheDocument(); }); test自定义颜色生效', () => { render( <div style={{ width: '800px', height: '300px' }}> <BarChart data={chartData} color="#ff4444" /> </div> ); const bars = screen.getAllByTestId('bar-chart-bar'); bars.forEach(bar => { expect(bar).toHaveStyle('fill: #ff4444'); }); });
内容的提问来源于stack exchange,提问作者Shashika Virajh
相关产品推荐
相关产品推荐

