这是我的DashboardPage组件:
export const DashboardPage = (props) => {
const [mounted, setMounted] = useState(false);
const { index } = props;
let navigate = useNavigate();
useEffect(() => {
if (mounted === false) {
setMounted(true);
index();
}
}, [mounted, index]);
const optionNUsersPerCompany = {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Utenti per azienda'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %'
},
}
},
series: [{
name: 'Utenti',
colorByPoint: true,
data: getDataUsersPerCompany(props.items),
point: {
events: {
click: (e) => {
console.log(e);
props.setCompanyIdInUsersStore(e.target.point.idCompany);
return navigate(PATH_USERS);
}
}
}
}]
}
return (
<Chart options={optionNUsersPerCompany} />
)
}
const mapDispatchToProps = (dispatch) => {
return {
index: () => dispatch(statsActions.index()),
setCompanyIdInUsersStore: (id) => dispatch(companiesActions.setCompanyIdInUsersStore(id)),
};
}
const mapStateToProps = (state) => {
return {
items: state.stats.items,
}
};
export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage);
这是简单的 highcharts 组件:
import React, { useState } from "react";
import HighchartsReact from "highcharts-react-official";
import Highcharts from 'highcharts';
export default React.memo(function Chart(props) {
const [currentOptions, setCurrentOptions] = useState({});
/**
* Questo controllo serve a non re-draware per due volte di seguito i containers
*/
if (JSON.stringify(props.options) !== JSON.stringify(currentOptions)) {
setCurrentOptions(props.options);
}
return (
<HighchartsReact
highcharts={Highcharts}
options={currentOptions}
immutable={true}
/>
);
});
我想在React Highcharts中用Jest测试plotOptions上的点击。这是从Jest得到的HTML页面:
<div>
<div
data-highcharts-chart="1"
style="overflow: hidden;"
>
<div
class="highcharts-container "
dir="ltr"
id="highcharts-r3a94y8-149"
style="position: relative; overflow: hidden; width: 600px; height: 400px; text-align: left; line-height: normal; z-index: 0; user-select: none; outline: none;"
>
<svg
class="highcharts-root"
height="400"
style="font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Arial, Helvetica, sans-serif; font-size: 12px;"
version="1.1"
viewBox="0 0 600 400"
width="600"
xmlns="http://www.w3.org/2000/svg"
>
<desc>
Created with Highcharts 10.1.0
</desc>
<defs>
<clippath
id="highcharts-r3a94y8-151-"
>
<rect
fill="none"
height="375"
width="580"
x="0"
y="0"
/>
</clippath>
</defs>
<rect
class="highcharts-background"
fill="#ffffff"
height="400"
rx="0"
ry="0"
width="600"
x="0"
y="0"
/>
<rect
class="highcharts-plot-background"
fill="none"
height="375"
width="580"
x="10"
y="10"
/>
<rect
class="highcharts-plot-border"
data-z-index="1"
fill="none"
height="375"
width="580"
x="10"
y="10"
/>
<g
class="highcharts-series-group"
data-z-index="3"
>
<g
class="highcharts-series highcharts-series-0 highcharts-pie-series highcharts-tracker"
data-z-index="0.1"
opacity="1"
style="cursor: pointer;"
transform="translate(10,10) scale(1 1)"
>
<path
class="highcharts-point highcharts-color-0"
d="M 290 175 A 0 0 0 0 1 290 175 L 290 175 A 0 0 0 0 0 290 175 Z"
fill="#7cb5ec"
opacity="1"
stroke="#ffffff"
stroke-linejoin="round"
stroke-width="1"
transform="translate(0,0)"
/>
</g>
<g
class="highcharts-markers highcharts-series-0 highcharts-pie-series"
data-z-index="0.1"
opacity="1"
transform="translate(10,10) scale(1 1)"
/>
</g>
<text
class="highcharts-title"
data-z-index="4"
style="color: rgb(51, 51, 51); font-size: 18px; fill: #333333;"
text-anchor="middle"
x="300"
y="24"
>
Utenti per azienda
</text>
<text
class="highcharts-subtitle"
data-z-index="4"
style="color: rgb(102, 102, 102); fill: #666666;"
text-anchor="middle"
x="300"
y="10"
/>
<text
class="highcharts-caption"
data-z-index="4"
style="color: rgb(102, 102, 102); fill: #666666;"
text-anchor="start"
x="10"
y="397"
/>
<g
class="highcharts-data-labels highcharts-series-0 highcharts-pie-series highcharts-tracker"
data-z-index="6"
opacity="0"
style="cursor: pointer;"
transform="translate(10,10) scale(1 1)"
>
<path
class="highcharts-data-label-connector highcharts-color-0"
d="M 295 370 C 290 370 290 352 290 346 L 290 340"
fill="none"
stroke="#7cb5ec"
stroke-width="1"
/>
<g
class="highcharts-label highcharts-data-label highcharts-data-label-color-0"
data-z-index="1"
style="cursor: pointer;"
transform="translate(300,360)"
>
<text
data-z-index="1"
style="color: rgb(0, 0, 0); font-size: 11px; font-weight: bold; fill: #000000;"
x="5"
y="16"
>
<tspan
style="font-weight: bold;"
>
acme
</tspan>
: 100.0 %
</text>
</g>
</g>
<g
class="highcharts-legend highcharts-no-tooltip"
data-z-index="7"
>
<rect
class="highcharts-legend-box"
fill="none"
height="8"
rx="0"
ry="0"
visibility="hidden"
width="8"
x="0"
y="0"
/>
<g
data-z-index="1"
>
<g />
</g>
</g>
<text
class="highcharts-credits"
data-z-index="8"
style="cursor: pointer; color: rgb(153, 153, 153); font-size: 9px; fill: #999999;"
text-anchor="end"
x="590"
y="395"
>
Highcharts.com
</text>
</svg>
</div>
</div>
</div>
- 我想获取
g
元素并单击它
render(<BrowserRouter><DashboardPage store={store} /></BrowserRouter>);
const company = screen.getAllByRole('g');
但我得到了:
TestingLibraryElementError: Unable to find an accessible element with the role "g"
There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the `hidden` option to `true`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
- 我尝试通过类名获取元素:
it('Can handle handleOnUserClick on Chart', async () => {
let initialState = {
stats: {
items: {
nUsersPerCompany: [
{
company: "demolitori",
qty: 5,
id: 16
}
]
}
},
setCompanyIdInUsersStore: () => {},
};
let store = mockStore(initialState);
const { container } = render(<BrowserRouter><DashboardPage store={store} /></BrowserRouter>);
// This console.log outputs the previous HTML code
console.log(prettyDOM(container));
const company = await container.getElementsByClassName("highcharts-label");
console.log(company);
fireEvent.click(company);
});
但是对于上一个console.log(company)
,我得到了一个空的HTML集合:
HTMLCollection {}
我也试着删除async
/await
模式,但没有运气。
我试着用途:
const {container} = render(<BrowserRouter><DashboardPage store={store} /></BrowserRouter>);
console.log(prettyDOM(container))
const path = container.getElementsByClassName("highcharts-color-0");
console.log(prettyDOM(path[0]))
fireEvent.click(path[0]);
测试本身工作,但覆盖率抱怨缺少点击e中的箭头功能
point: {
events: {
click: (e) => {
props.setCompanyIdInUsersStore(e.target.point.idCompany);
return navigate(PATH_USERS);
}
}
}
1条答案
按热度按时间8nuwlpux1#
覆盖率统计信息是正确的,因为Highcharts使用SVG和其他组件呈现元素(path、rect等),它们不支持通过DOM模拟单击事件。如果您用mouseOver替换click,您的测试覆盖率将达到100%,Highcharts团队可能正在做一些自定义实现来实现点击处理程序,我们需要利用它来解决您的用例。@波塔切克指出了正确的做法。
代码修改:
callback是HighCharts react wrapper上的一个属性,它在呈现图表时执行,并返回图表的示例。
现在我们修改DashboardPage组件的测试用例,如下所示:
因此,我们在测试中只使用回调函数来提高覆盖率。这应该会将DashboardPage组件的覆盖率提高到100%。