bounty明天到期。回答此问题有资格获得+200声望奖励。Shruti sharma正在寻找规范答案。
我有下面的测试用例.请不要阅读整个代码.(它没有必要).我想说的是我写了至少100倍,检查与chatgpt,谷歌巴德仍然无法使这个测试用例成功.对于所有其他组件所有的测试用例都成为成功.下面是我的代码.(仅供参考).
import React, { useEffect, useRef, useState } from 'react';
import { Chart, ChartConfiguration, registerables } from 'chart.js';
import './EmailLineChart.styles.css';
import { useUser } from '../../common/context/context';
const DataLineChart: React.FC = () => {
const chartRef = useRef<HTMLCanvasElement>(null);
const chartInstanceRef = useRef<Chart | null>(null);
const [data, setData] = useState<{ month: string; success: number; failed: number; processing?: number }[]>([]);
const [downloadFormat, setDownloadFormat] = useState<string>('chart');
const [filterMonth, setFilterMonth] = useState<string>('');
const [chartType, setChartType] = useState<'line'|'bar'>('line');
const baseUrl = process.env.REACT_APP_BASE_URL;
let url = `${baseUrl}/email/reports/count?type=year&tag=${tag}&service_name=${servicename}`;
const tenantData = useUser();
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
const apiData = await response.json();
const monthlyReports = apiData.monthlyReports;
if (!monthlyReports) {
console.error('No monthlyReports data in API response');
return; // Early return if no monthlyReports data
}
const chartData = Object.keys(monthlyReports).map((month) => ({
month,
success: monthlyReports[month].SUCCESS,
failed: monthlyReports[month].FAILED,
processing: monthlyReports[month].PROCESSING || 0,
}));
// Sort data by month
chartData.sort((a, b) => new Date(a.month).getTime() - new Date(b.month).getTime());
setData(chartData);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
}, []);
useEffect(() => {
if (chartInstanceRef.current) {
chartInstanceRef.current.destroy();
}
if (chartRef.current && downloadFormat === 'chart') {
Chart.register(...registerables);
const ctx = chartRef.current.getContext('2d');
const filteredData = filterMonth ? data.filter((item) => item.month === filterMonth) : data;
if (ctx) {
const gradient1 = ctx.createLinearGradient(0, 0, 0, 400);
gradient1.addColorStop(0, 'rgba(75, 192, 192, 0.6)');
gradient1.addColorStop(1, 'rgba(75, 192, 192, 0)');
const gradient2 = ctx.createLinearGradient(0, 0, 0, 400);
gradient2.addColorStop(0, 'rgba(255, 99, 132, 0.6)');
gradient2.addColorStop(1, 'rgba(255, 99, 132, 0)');
const config: ChartConfiguration<'line'|'bar'> = {
type: chartType,
data: {
labels: filteredData.map((item) => item.month),
datasets: [
{
label: 'Success',
data: filteredData.map((item) => item.success),
borderColor: 'rgba(75, 192,198, 0.9)',
fill: true,
backgroundColor:'rgba(75, 192, 192, 0.3)',
pointBackgroundColor: 'rgba(75, 192, 192, 0.9)',
pointBorderColor:'rgba(75, 250, 192, 0.9)',
pointHoverBackgroundColor: 'rgba(75, 350, 192, 0.9)',
pointHoverBorderColor: 'rgba(75, 350, 192, 0.9)',
pointHoverRadius: 8,
pointHoverBorderWidth: 5,
tension: 0.1,
},
{
label: 'Failed',
data: filteredData.map((item) => item.failed),
borderColor: 'rgba(255, 99, 132, 0.4)',
fill: true,
backgroundColor: 'rgba(255, 99, 132, 0.2)',
pointBackgroundColor: 'rgba(255, 99, 132, 0.3)',
pointBorderColor: 'rgba(255, 99, 132, 0.9)',
pointHoverBackgroundColor: 'rgba(255, 99, 132, 0.3)',
pointHoverBorderColor: 'rgba(255, 99, 132, 0.3)',
pointHoverRadius: 8,
pointHoverBorderWidth: 5,
tension: 0.1,
},
],
},
options: {
responsive: true,
animation: {
duration: 2000,
easing: 'easeInOutBounce',
},
scales: {
x: {
title: {
display: true,
text: 'Month',
},
grid: {
color: 'gray', // change this as needed
display: false,
},
ticks: {
color: 'black', // change this as needed
font: {
size: 10,
}
},
stacked:true
},
y: {
title: {
display: true,
text: 'Number of Emails',
},
ticks: {
color: 'black', // change this as needed
font: {
size: 10,
}
},
grid: {
color: 'gray', // change this as needed
display: false,
},
stacked:true,
},
}
}
,
};
chartInstanceRef.current = new Chart(ctx, config);
}
}
}, [downloadFormat, data, filterMonth]);
useEffect(() => {
if (chartInstanceRef.current) {
const chart = chartInstanceRef.current;
chart.data.labels = data.map((item) => item.month);
chart.data.datasets[0].data = data.map((item) => item.success||0);
chart.data.datasets[1].data = data.map((item) => item.failed||0);
chart.update();
}
}, [data]);
const filteredData = filterMonth ? data.filter((item) => item.month === filterMonth) : data;
const isChartSelected = downloadFormat === 'chart';
return (
<div className='chart'>
<canvas ref={chartRef} className='chart-wrapper'></canvas>
</div>
);
};
export default DataLineChart;
字符串
由于我的代码使用自定义钩子和chart.js,所以很难写案例,但它只在渲染时出错。我根本无法前进。
我写了下面的测试用例。
import React from 'react';
import { render } from '@testing-library/react';
import { Chart, registerables } from 'chart.js'; // Import Chart.js as usual
import DataLineChart from './DataLineChart';
jest.mock('../../common/context/context', () => ({
useUser: jest.fn(() => ({ tenantData: { tenantId: 'mockedTenantId' } })),
}));
jest.mock('chart.js')
describe('DataLineChart', () => {
it('renders without errors', () => {
render(<DataLineChart />);
});
});
型
但错误即将来临
"TypeError: undefined is not iterable (cannot read property Symbol(symbol.iterator)"
型
基本上错误来自这一行。Chart.register(...registerables);
。你们中的任何人都可以指导如何模拟chart.js
。如何测试这些类型的组件?我有95%代码覆盖率和挣扎严重的最后10天.我用了很多方法来模拟chart.js
,但没有任何工作. chart.js我使用3.9.1版本.如果任何建议修改代码或测试用例,将真的很有帮助。我使用jest
。我也可以提供完整版本的代码,如果它是有帮助的,无论如何。
1条答案
按热度按时间wgeznvg71#
我认为这里的问题是你试图在一个超级大的函数中做太多的事情。理想情况下,你需要将
useEffects()
从React Functional Component中取出,然后将它们分解为更小的可测试函数。如果我在写这个,我会把每个效果放在它们自己的文件中,然后把每个效果分解成更小的函数,然后通过一个非常小的
useEffect()
调用来调用。这样,您就可以为每个功能编写单独的测试。
我个人的经验法则是,如果一个函数做多个离散的事情,它需要拆分成更小的函数。一旦你开始用清晰的函数名来做这件事,你的代码库立即变得自我文档化,如果你在一年后不得不回到这段代码,你会感谢你的。
这很可能不是你想要的答案,但很久以前,它是我收到的最好的编码建议之一。