У меня проблема при тестировании компонента, который отображает пару текстовых полей, значок и диаграмму.
Я рендерим диаграмму на <canvas>
и для этого использую ловушку реагирования useRef
и все работает прекрасно.
Моя проблема в том, когда я пытаюсь отрендерить компонент в моем модульном тесте. Для этой цели я использую шут и энзим, поэтому в этом процессе участвуют следующие файлы:
React Component
import React, { useEffect, useRef } from 'react';
import Chart from 'chart.js';
import { useWidgetConfiguration } from '../utils/SummitHooks';
const styles = {
canvas: { padding: '30px 30px' },
};
const widgetProperties = {
title: { type: 'string', default: '' },
percent: { type: 'number' },
};
const DougnutWithTextWidget = props => {
const { widgetConf } = props;
const chartRef = useRef();
const widgetDisplayValues = useWidgetConfiguration(
widgetProperties,
widgetConf,
);
useEffect(() => {
if (chartRef.current) {
new Chart(chartRef.current.getContext('2d'), {
type: 'doughnut',
data: {
labels: ['', widgetDisplayValues.title],
datasets: [
{
data: [
parseInt(100 - parseInt(widgetDisplayValues.percent)),
parseInt(widgetDisplayValues.percent),
],
backgroundColor: ['#f4f4f4', '#377d28'],
},
],
text: widgetDisplayValues.title,
},
options: {
animation: {
animateScale: true,
animateRotate: true,
},
cutoutPercentage: 75,
tooltips: false,
},
});
}
}, [widgetDisplayValues, chartRef]);
Chart.defaults.global.legend = false;
return (
<div className='uk-container-expand'>
<div className='widget-account-health-outer'>
<div className='widget-account-health-inner'>
<h1 className='uk-text-center'>{widgetDisplayValues.percent}%</h1>
<span className='uk-h5 uk-text-bold'>
{widgetDisplayValues.title}
</span>
</div>
<canvas
ref={chartRef}
height='400'
width='400'
style={styles.canvas}
></canvas>
</div>
</div>
);
};
export default DougnutWithTextWidget;
Тестовый файл
import React from 'react';
import { mount } from 'enzyme';
import DougnutWithTextWidget from '../components/organisms/DougnutWithTextWidget';
describe('Testing the Atomic Component <AccountBarChartWidget />', () => {
let atomicComponent;
const widgetConf = {
title: 'GOALS HEALTH',
percent: 57,
chartType: 'doughnut',
linkTo: '',
};
beforeAll(() => {
atomicComponent = mount(<DougnutWithTextWidget widgetConf={widgetConf} />);
});
afterAll(() => {
atomicComponent.unmount();
});
describe('Validate that the Atomic Component is displaying the data provided as wdgetConf', () => {
it('Ensure that the right amount has been displayed', () => {
// A simple test just for making sure the component is rendering without any problem
expect(2 + 2).toEqual(4);
});
});
});
В этот момент, когда я использую либо shallow
, либо render
, тест работает нормально, но моя цель - на самом деле mount
компонент, чтобы убедиться, что график был
Это ошибка, которую я получаю:
Testing the Atomic Component <AccountBarChartWidget />
Validate that the Atomic Component is displaying the data provided as wdgetConf
✕ Ensure that the right amount has been displayed (3ms)
● Testing the Atomic Component <AccountBarChartWidget /> › Validate that the Atomic Component is displaying the data provided as wdgetConf › Ensure that the right amount has been displayed
TypeError: Cannot read property 'length' of null
24 | useEffect(() => {
25 | if (chartRef.current) {
> 26 | new Chart(chartRef.current.getContext('2d'), {
| ^
27 | type: 'doughnut',
28 | data: {
29 | labels: ['', widgetDisplayValues.title],
at Object.acquireContext (node_modules/chart.js/dist/Chart.js:7739:19)
at Chart.construct (node_modules/chart.js/dist/Chart.js:9307:26)
at new Chart (node_modules/chart.js/dist/Chart.js:9294:7)
at DougnutWithTextWidget (src/components/organisms/DougnutWithTextWidget.js:26:7)
at commitHookEffectList (node_modules/react-dom/cjs/react-dom.development.js:22030:26)
at commitPassiveHookEffects (node_modules/react-dom/cjs/react-dom.development.js:22064:11)
at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:336:14)
at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:385:16)
at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:440:31)
at flushPassiveEffectsImpl (node_modules/react-dom/cjs/react-dom.development.js:25392:7)
at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:697:12)
at runWithPriority$2 (node_modules/react-dom/cjs/react-dom.development.js:12149:10)
at flushPassiveEffects (node_modules/react-dom/cjs/react-dom.development.js:25361:12)
at Object.<anonymous>.flushWork (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1041:10)
at Object.act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1155:9)
at wrapAct (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:354:13)
at Object.render (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:423:16)
at new ReactWrapper (node_modules/enzyme/src/ReactWrapper.js:115:16)
at mount (node_modules/enzyme/src/mount.js:10:10)
at Object.beforeAll (src/__tests__/dougutWithTextWidget.test.js:16:23)
Кто-нибудь пытался проверить что-то подобное и может указать мне правильное направление?