bert
bert

Reputation: 4059

How to test with Jest that ReactDOM.render has been called when it has been wrapped in a conditional?

I have the following react component and it conditionally calls ReactDOM.render if root === true in order to satisfy flow:

import React from 'react'
import ReactDOM from 'react-dom'

import App from './App'

const root = document.getElementById('root')

if (root !== null) {
  ReactDOM.render(<App />, root)
}

The problem is that this test no longer equals true, presumably because the conditional wrapping needs to be mocked as true or something but I can't figure it out.

import ReactDOM from 'react-dom'

jest.mock('react-dom')

require('../index')

test('Renders the application', () => {
  expect(ReactDOM.render).toBeCalled()
})

How do I need to update my test to check that ReactDOM.render is called?

Upvotes: 3

Views: 13120

Answers (1)

Shubham Gupta
Shubham Gupta

Reputation: 2646

I think this test case is redundant since you will have to mock document and render function so basically what you are testing is just the conditional. But there could be similar use case. You should make following changes to code.

function renderToDOM() {
    if (root !== null) {
        ReactDOM.render(<App />, root)
    }
}
renderToDOM();
export {renderToDOM};

By making this change we will able to write a clean test and test only this piece of code independently. Following is the test case which worked for me. Had to mock ReactDOM.render as well as document.getElementById to get the test case working.

import ReactDOM from "react-dom";
import { mock } from "jest";
import { renderToDOM } from "./index";

describe("test ReactDOM.render", () => {
  const originalRender = ReactDOM.render;
  const originalGetElement = global.document.getElementById;
  beforeEach(() => {
    global.document.getElementById = () => true;
    ReactDOM.render = jest.fn();
  });
  afterAll(() => {
    global.document.getElementById = originalGetElement;
    ReactDOM.render = originalRender;
  });
  it("should call ReactDOM.render", () => {
    renderToDOM();
    expect(ReactDOM.render).toHaveBeenCalled();
  });
});

Following is the code sandbox link where you can see this test running and test cases are passing. https://codesandbox.io/s/7wr0k7qmq

Upvotes: 7

Related Questions