unit-testingmaterial-uireact-test-renderer

Can't test Material-ui Modal with react test renderer


When trying to write a simple test with jest lib for Modal component like this

import { Modal } from '@material-ui/core';
import React from 'react';
import TestRenderer from 'react-test-renderer';

describe('Material Modal test', () => {
  it('It should render', () => {
    const testRenderer = TestRenderer.create(
      <Modal open={true}>
        <div>Test</div>
      </Modal>
    );

    console.log(testRenderer.toJSON());
  });
});

I get an error:

 console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:120
      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.
          in div (created by ForwardRef(Modal))
          in ForwardRef(Portal) (created by ForwardRef(Modal))
          in ForwardRef(Modal) (at spinnerWaitingWindow.spec.tsx:10)
    console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Uncaught [TypeError: parentInstance.children.indexOf is not a function]

Did anyone have a clue why this happens and how to setup test library?


Solution

  • You can mock partially react-dom to escape the createPortal function trying to attach to a non existing dom element. Here's an example:

    jest.mock('react-dom', () => {
        const actualModule = jest.requireActual('react-dom');
        return {
            ...actualModule,
            createPortal: node => node,
        };
    });
    

    To be on the safe side it's always a good idea to perform mocks cleanup after the suite has finished e.g.:

    describe('Material modal test`, () => {
    
     afterAll(() => {
        jest.resetAllMocks();
     });
    
    })