recharts: ResponsiveContainer cannot be rendered and hence cannot be tested using react testing library

  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

Edit on CodeSandbox

Steps to reproduce

  1. Use ResponsiveContainer to render a chart
  2. Render the chart component with react testing library

What is expected?

The chart should get rendered

What is actually happening?

<div class="recharts-responsive-container makeStyles-chart-21" style="width: 100%; height: 300px;">
    <div style="position: absolute; width: 0px; height: 0px; visibility: hidden; display: none;"/>
</div>

The chart is hidden with 0 height and width. No dom nodes are created for the chart.

Environment Info
Recharts v1.8.5
React 16.13.0
System macOS Mojave 10.14.6
Browser React testing library

The chart is rendered while testing if ResponsiveContainer is replaced with a div.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16

Most upvoted comments

You’re a life-saver, @krzysu! This was making me crazy. The only thing I’ll add is that I had to return all the other recharts components as-is with spread syntax on the original module.

jest.mock('recharts', () => {
    const OriginalModule = jest.requireActual('recharts');

    return {
        ...OriginalModule,
        ResponsiveContainer: ({ height, children }) => (
            <OriginalModule.ResponsiveContainer width={800} height={height}>
                {children}
            </OriginalModule.ResponsiveContainer>
        ),
    };
});

Thanks again!

This solutions worked perfectly fine for me:

  • replace ResponsiveContainer by simple <div> element with fixed width;
  • it also removes the warning message you get when you try to use OriginalRechartsModule.ResponsiveContainer;
jest.mock('recharts', () => {
  const OriginalRechartsModule = jest.requireActual('recharts');

  return {
    ...OriginalRechartsModule,
    ResponsiveContainer: ({ height, children }: any) => (
      <div className="recharts-responsive-container" style={{ width: 800, height }}>
        {children}
      </div>
    ),
  };
});

you mock ResponsiveContainer in your test, something like below:

jest.mock('recharts', () => {
  const OriginalResponsiveContainerModule = jest.requireActual('recharts');

  return {
    ResponsiveContainer: ({ height, children }) => (
      <OriginalResponsiveContainerModule.ResponsiveContainer
        width={800}
        height={height}
      >
        {children}
      </OriginalResponsiveContainerModule.ResponsiveContainer>
    ),
  };
});

Setting the aspect and a fixed width (or height) worked for me to make the warning disappear, i.e.

jest.mock('recharts', () => {
    const OriginalModule = jest.requireActual('recharts')
    return {
        ...OriginalModule,
        // eslint-disable-next-line react/display-name, react/prop-types
        ResponsiveContainer: ({ children }) => (
            <OriginalModule.ResponsiveContainer width={100} aspect={1}>
                {children}
            </OriginalModule.ResponsiveContainer>
        )
    }
})

Just another dirty hack, but it works at least for me.

I was previously using this work-around inspired by @krzysu 's comment

You’re a life-saver, @krzysu! This was making me crazy. The only thing I’ll add is that I had to return all the other recharts components as-is with spread syntax on the original module.

jest.mock('recharts', () => {
    const OriginalModule = jest.requireActual('recharts');

    return {
        ...OriginalModule,
        ResponsiveContainer: ({ height, children }) => (
            <OriginalModule.ResponsiveContainer width={800} height={height}>
                {children}
            </OriginalModule.ResponsiveContainer>
        ),
    };
});

Thanks again!

and it worked great, but I also ended up with a bunch of warnings in the console log when running tests…

console.warn node_modules/recharts/lib/util/LogUtils.js:23
      The width(800) and height(500) are both fixed numbers,
             maybe you don't need to use a ResponsiveContainer.

I’m now using a manual mock in Jest to mock the recharts module that removes the ResponsiveContainer when testing and just renders the child component (which is one of the charts e.g. BarChart, LineChart, etc.) with a fixed width (height is already fixed in my usages), so no more warnings in the console and the chart is rendered in the DOM for testing.

file: /__mocks__/recharts.js

import { cloneElement } from 'react';

// re-export everything from recharts
export * from 'recharts';

// export override of ResponsiveContainer component
export const ResponsiveContainer = ({ children, height }) => cloneElement(children, { width: 500, height });

Oh, and unfortunately, the method described here wouldn’t work for me since I’m not testing my chart directly but testing at the app/page level and don’t want to have to pass a width prop down multiple component levels to get to my chart.

Alternatively, you can set width as a prop on your chart component, and pass that value to ResponsiveContainer’s width property. Pass “100%” (or whatever percent) to the width prop regularly, and pass it a fixed value, like 1, in your test.

The div solution referenced above does not work for me.