Исключение при юнит-тесте с использованием useRef (), jest и энзима - PullRequest
0 голосов
/ 29 января 2020

У меня проблема при тестировании компонента, который отображает пару текстовых полей, значок и диаграмму.

Я рендерим диаграмму на <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)

Кто-нибудь пытался проверить что-то подобное и может указать мне правильное направление?

1 Ответ

1 голос
/ 29 января 2020

Мне наконец удалось взломать эту проблему. Мне требовалась поддержка тега <canvas> в тестовом файле, и просто импорт jest-canvas-mock сделал свое дело.

...