如何使用 Jest 测试 ReactDOM.render 已被包含在条件中时已被调用?

ber*_*ert 2 javascript reactjs jestjs

我有以下反应组件,它有条件地调用ReactDOM.renderifroot === true以满足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)
}
Run Code Online (Sandbox Code Playgroud)

问题是这个测试不再等于真,大概是因为条件包装需要被模拟为真或其他东西,但我无法弄清楚。

import ReactDOM from 'react-dom'

jest.mock('react-dom')

require('../index')

test('Renders the application', () => {
  expect(ReactDOM.render).toBeCalled()
})
Run Code Online (Sandbox Code Playgroud)

我需要如何更新我的测试来检查它ReactDOM.render是否被调用?

Shu*_*pta 6

我认为这个测试用例是多余的,因为你必须模拟文档和渲染函数,所以基本上你正在测试的只是条件。但可能有类似的用例。您应该对代码进行以下更改。

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

通过进行此更改,我们将能够编写干净的测试并仅独立测试这段代码。以下是对我有用的测试用例。必须模拟 ReactDOM.render 和 document.getElementById 才能使测试用例正常工作。

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

以下是代码沙箱链接,您可以在其中看到此测试正在运行并且测试用例正在通过。 https://codesandbox.io/s/7wr0k7qmq