Jest - Testing modals in React gives error
Asked Answered
B

3

8

I am using react-test-renderer with Jest to test react components. But if I test a react-mui modal dialog like this:

describe('Dashboard', function () {
  let dashboard;
  beforeEach(async () => {
    testRenderer = TestRenderer.create(<MemoryRouter><Route component={Dashboard} /></MemoryRouter>);
    dashboard = testRenderer.root.findByType(Dashboard);
    await waitForExpect(() => expect(dashboard.instance.state.hasLoaded).toBeTruthy());
  });


  it('opens dialog on clicking the new class', async () => {
    const button = testRenderer.root.findByType(Button);
    expect(dashboard.instance.state.showDialog).toBeFalsy();
    button.props.onClick();
    expect(dashboard.instance.state.showDialog).toBeTruthy();
  });
});

But, then I get an error:

Error: Failed: "Error: Uncaught 'Warning: An invalid container has been provided. This may indicate that another renderer is being used in addition to the test renderer. (For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) This is not supported.%s'

How should I test then react portals to make this test work?

Birmingham answered 22/5, 2019 at 13:27 Comment(1)
seems like known issue github.com/facebook/react/issues/11565 with only workaround to mock ReactDOM.createPortalInduration
S
12

Try putting this in your tests:

beforeAll(() => {
    ReactDOM.createPortal = jest.fn((element, node) => {
        return element
    })
});
Sixtasixteen answered 24/9, 2019 at 9:15 Comment(4)
How does this code work? What is the reason that we need to put it?Moneylender
@MaryamSaeidi I think you should add import ReactDOM from 'react-dom and add the beforeAll code just below the imports.Sanches
I tried this, but got Cannot set property 'scrollTop' of null.Sanches
Error: Uncaught [TypeError: Cannot read properties of null (reading 'setAttribute')] at reportException (/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24) The above error occurred in the <ForwardRef(Portal)> component: at Portal (/node_modules/@mui/base/node/Portal/Portal.js:33:5) Error: Uncaught [TypeError: Cannot read properties of null (reading 'scrollTop')] at reportException (/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)Katlaps
D
10

Based on Oliver's answer, but for TypeScript users:

describe("Tests", () => {
  const oldCreatePortal = ReactDOM.createPortal;
  beforeAll(() => {
    ReactDOM.createPortal = (node: ReactNode): ReactPortal =>
      node as ReactPortal;
  });

  afterAll(() => {
    ReactDOM.createPortal = oldCreatePortal;
  });
});
Donella answered 6/2, 2022 at 21:27 Comment(0)
C
0

For me, the existing solutions don't address the root cause.

I needed to add jest mocks for all the sub-components in the component I was testing.

For example, consider this JSX that I want to test:

import { CustomTextInput } from 'components/CustomTextInput';
import { CustomButton } from 'components/CustomButton';

return (
  <>
    <CustomTextInput />
    <CustomButton />
  </>
)

I need to add mocks for CustomTextInput and CustomButton in my test file like this:

jest.mock(
  'components/CustomTextInput',
  () => ({ default: 'mock-CustomTextInput' }),
);

jest.mock(
  'components/CustomButton',
  () => ({ default: 'mock-CustomButton' }),
);
Cookbook answered 15/7, 2022 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.