react-chartjs-2: Testing with jest / enzyme / jsdom - Failed to create chart: can't acquire context from the given item

Using the DoughnutChart example

doughnutChart.js

import React from 'react'
import { Doughnut } from 'react-chartjs-2'

const data = {
  labels: [
    'Red',
    'Green',
    'Yellow',
  ],
  datasets: [{
    data: [
      300,
      50,
      100,
    ],
    backgroundColor: [
      '#FF6384',
      '#36A2EB',
      '#FFCE56',
    ],
    hoverBackgroundColor: [
      '#FF6384',
      '#36A2EB',
      '#FFCE56',
    ],
  }],
}

const DoughnutChart = props => (
  <div className="chart-wrapper">
    <Doughnut
      data={data}
    />
  </div>
)

export default DoughnutChart

doughnutChart.spec.js

import React from 'react'

import DoughnutChart from './doughnutChart'

it('Renders a DoughnutChart', () => {
  const wrapper = mount(
    <DoughnutChart />,
  )
  expect(wrapper).toMatchSnapshot()
})

Error

Failed to create chart: can't acquire context from the given item
      
      at CustomConsole.Object.<anonymous>.console.error (tools/jestSetup.js:37:9)
      at Chart.construct (node_modules/chart.js/src/core/core.controller.js:116:13)
      at new Chart (node_modules/chart.js/src/core/core.js:7:8)
      at ChartComponent.renderChart (node_modules/react-chartjs-2/lib/index.js:259:29)
      at ChartComponent.componentDidMount (node_modules/react-chartjs-2/lib/index.js:81:12)
      at node_modules/react-dom/lib/ReactCompositeComponent.js:264:25
      at measureLifeCyclePerf (node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)
      at node_modules/react-dom/lib/ReactCompositeComponent.js:263:11
      at CallbackQueue.notifyAll (node_modules/react-dom/lib/CallbackQueue.js:76:22)
      at ReactReconcileTransaction.close (node_modules/react-dom/lib/ReactReconcileTransaction.js:80:26)
      at ReactReconcileTransaction.closeAll (node_modules/react-dom/lib/Transaction.js:209:25)
      at ReactReconcileTransaction.perform (node_modules/react-dom/lib/Transaction.js:156:16)
      at batchedMountComponentIntoNode (node_modules/react-dom/lib/ReactMount.js:126:15)
      at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-dom/lib/Transaction.js:143:20)
      at Object.batchedUpdates (node_modules/react-dom/lib/ReactDefaultBatchingStrategy.js:62:26)
      at Object.batchedUpdates (node_modules/react-dom/lib/ReactUpdates.js:97:27)
      at Object._renderNewRootComponent (node_modules/react-dom/lib/ReactMount.js:319:18)
      at Object._renderSubtreeIntoContainer (node_modules/react-dom/lib/ReactMount.js:401:32)
      at Object.render (node_modules/react-dom/lib/ReactMount.js:422:23)
      at Object.renderIntoDocument (node_modules/react-dom/lib/ReactTestUtils.js:91:21)
      at renderWithOptions (node_modules/enzyme/build/react-compat.js:200:24)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:94:59)
      at mount (node_modules/enzyme/build/mount.js:19:10)
      at Object.<anonymous> (src/elements/doughnutChart/doughnutChart.spec.js:6:17)
          at Promise (<anonymous>)
      at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
          at <anonymous>

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 10
  • Comments: 35

Commits related to this issue

Most upvoted comments

Workaround is to mock out the chart for enzyme mounting (or just use a shallow wrapper)

    jest.mock('react-chartjs-2', () => ({
      Doughnut: () => null,
    }))

In my case the solution provided by csi-lk wasn’t working because I was calling jest.mock() inside describe() and even inside it(), but it must be outermost scope. Perhaps that’s obvious but it wasn’t for me.

I had the same issue with @sgavathe After looking at their test-setup – https://github.com/reactchartjs/react-chartjs-2/blob/master/test/setup.js

I just had to add the code below to eliminate the console errors while also rendering canvas in my jest tests

import 'jest-canvas-mock';

class ResizeObserver {
  observe() {}
  unobserve() {}
  disconnect() {}
}

window.ResizeObserver = ResizeObserver;

The issue with this mock is

jest.mock('react-chartjs-2', () => ({
  Bar: () => null, // add any additional chart types here
  Line: () => null
}));

you can’t then test against canvas, it won’t render canvas inside your screen container! This test will fail!

 const canvas = screen.getByTestId('testdiv').querySelector('canvas') ;
 expect(canvas).toBeInTheDocument();

@schlattk do you have the setup-jest.js file setup properly in your package.json similar to this.

  "jest": {
    "setupFiles": [
      "./shim.js",
      "./setup-jest.js"
    ]

I was trying to configure this in CRA generated app but it didn’t allow me. I searched and found that you can directly add following piece of code in ‘src/setupTests.js’ file. No need to do any additional jest configs.

import React, { Component } from 'react';

jest.mock('react-chartjs-2', () => ({
  Bar: () => null, // add any additional chart types here
  Line: () => null
}));

How can I test a component that use the library?!

@schlattk this is my setup-jest.js

import React, { Component } from 'react';

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16.3'; // change depending on what version of react

Enzyme.configure({ adapter: new Adapter() });

import $ from 'jquery';
global.$ = global.jQuery = $;

jest.mock('react-chartjs-2', () => ({
  Bar: () => null, // add any additional chart types here
  Line: () => null
}));

What type of charts are you attempting to use? Make sure you add it inside of the mock where my comment is at.

I have a BarChart component as follows:

  const BarChart = ({ data, options }: BarProps) => {
  const chartRef = useRef<ChartJS<"bar"> | null>(null);

  return (
    <Bar
      options={options}
      data={data}
      ref={chartRef}
      onClick={(event) => {
        const { current: chart } = chartRef;

        if (!chart) return;

        const dataset = getDatasetAtEvent(chart, event);
        const element = getElementAtEvent(chart, event);
        const elements = getElementsAtEvent(chart, event);

        // eslint-disable-next-line no-console
        console.info(dataset, element, elements);
      }}
    />
  );
};

I am trying to write unit tests for it however I keep getting the following error message when running the test

Failed to create chart: can’t acquire context from the given item

I can’t use the suggestion of

jest.mock('react-chartjs-2', () => ({ Bar: () => null }));

because it doesn’t render the canvas element

If you’re attaching a reference element to the chartjs component the above will not work directly as it’s a functional component, you’ll need to return a fake component forwarding the ref

If you’re using in your component like so:

   const barRef = useRef(null);
    <Bar ref={barRef} ... />

Then you’ll need to adjust the mock:

jest.mock('react-chartjs-2', () => {
  const { forwardRef } = require('react');
  const Line = forwardRef((props, ref)=> <div ref={ref} {...props}></div>);
  const Bar = forwardRef((props, ref)=> <div ref={ref} {...props}></div>);
  return {
    Line,
    Bar,
  };
});

Anyone has a solution for this issue without using:

jest.mock('react-chartjs-2', () => ({
  Doughnut: () => null,
}));

Because by doing that we can’t test against the canvas as @sgavathe mentioned.

Why is this issue CLOSED?

They are tacitly indicating that we should use vitest XD.

I had the same issue with @sgavathe After looking at their test-setup – https://github.com/reactchartjs/react-chartjs-2/blob/master/test/setup.js

I just had to add the code below to eliminate the console errors while also rendering canvas in my jest tests

import 'jest-canvas-mock';

class ResizeObserver {
  observe() {}
  unobserve() {}
  disconnect() {}
}

window.ResizeObserver = ResizeObserver;

This solved our issue with testing react-chartjs-2. We are using vitest. So we needed the vitest version.

yarn add --dev vitest-canvas-mock

And appended in our setup.js file image

Now our test is successful. image image image

Hi! I am facing the same issue. I am currently using the latest versions of react-chartjs-2 and chartjs. I tried the fix suggested by @joe-choi-dev and the one suggested by @lissettdm but didn’t work for me. Do you guys have a fix for this issue? Thanks!

It is also not working for me.

Hi, yes but apparently setup files are not supported in create react app - according to the error message in terminal, it works fine in any case though!

@csi-lk’s solution worked for me, be sure to put it in your setup-jest.js file.