【问题标题】:Document null when testing with Testing Library使用测试库进行测试时文档为空
【发布时间】:2020-11-16 20:40:08
【问题描述】:

我正在尝试在我的 react 应用程序中测试单个组件并收到以下错误:


    TypeError: Cannot read property 'clientWidth' of null

      20 | 
      21 |     resize = () => {
    > 22 |         const contentWidth = document.getElementById('root').clientWidth;

这是测试:

import React from 'react'
import { MemoryRouter } from 'react-router-dom'
import { render, screen } from '@testing-library/react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from '../store/reducer';
import Navigation from '../App/layout/AdminLayout/Navigation'

const store = createStore(reducer);

describe('Menu', () => {
  it('Estate Planning points to classic estate planning page', () => {
    render(
      <MemoryRouter>
        <Provider store={store}>
          <Navigation />
        </Provider>
      </MemoryRouter>
    );

    screen.debug()
  })
})

我尝试定义容器render(..., { container: document.body}),但得到了同样的错误。我不确定我错过了什么。

【问题讨论】:

    标签: react-testing-library


    【解决方案1】:

    您收到此错误是因为在使用 react-testing-library 运行测试时,您的文档不包含 ID 为“root”的元素。这可能是因为react-testing-library 将您的组件呈现到与ReactDOM(用于运行您的应用程序)不同的容器中。

    问题

    让我们看一下典型的 React 应用程序设置。

    <!-- public/index.html -->
    <html>
      <body>
        <div id="root"></div>
      </body>
    </html>
    
    // src/index.js
    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./components/App";
    
    ReactDOM.render(<App />, document.querySelector("#root"));
    
    // src/components/App.js
    import React from "react";
    
    const App = () => <div>Hello World!</div>;
    
    export default App;
    

    如我们所见,index.js 查找一个 id 为“root”的 HTML 元素,并在该元素内呈现我们的 App 组件。我们可以通过检查浏览器开发者工具中的元素来确认这种情况:

    <html>
      <body>
        <div id="root">
          <div>Hello World!</div>
        </div>
      </body>
    </html>
    

    现在,让我们编写一个简单的测试,看看 DOM 是什么样子的。

    // src/components/App.test.js
    import React from "react";
    import { render, screen } from "@testing-library/react";
    import App from "./App";
    
    test("renders the component", () => {
      render(<App />);
      screen.debug();
    });
    

    screen.debug() 打印 DOM 以进行调试。我们可以看到它不包含 id 为“root”的元素:

    <body>
      <div>
        <div>
          Hello World!
        </div>
      </div>
    </body>
    

    因此,您的测试与运行时的 DOM 容器略有不同。

    解决方案

    解决此问题的一种方法是重构您的代码,使其不依赖于“根”元素。另一种选择是告诉react-testing-library 在自定义容器中呈现您的组件。下面是一个可能看起来像的示例:

    // src/components/App.test.js
    import React from "react";
    import { render, screen } from "@testing-library/react";
    import App from "./App";
    
    test("renders the component in a specific container", () => {
      const container = document.createElement("div");
      container.id = "root";
    
      render(<App />, { container: document.body.appendChild(container) });
      screen.debug();
    });
    

    现在,我们可以在 DOM 中看到一个 id 为“root”的元素,因此您的组件应该能够找到该元素。

    <body>
      <div id="root">
        <div>
          Hello World!
        </div>
      </div>
    </body>
    

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 2021-07-14
      • 2019-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 2022-08-02
      • 2019-04-18
      相关资源
      最近更新 更多