【问题标题】:Testing Library : How to render the same component multiple times without coupling测试库:如何在不耦合的情况下多次渲染同一个组件
【发布时间】:2019-12-09 00:17:26
【问题描述】:

我正在使用 React Testing Library 和 Jest 来测试我的 React/Redux 应用程序。

我想在多个测试中测试同一个组件,而不是在每个实例之间共享组件的状态。

这样的……

import React from "react";
import {renderWithRedux} from '../testUtils';
import App from "../components/App";

describe("App", () => {

    test("does something as expected", async () => {
        const {container} = renderWithRedux(<App />);
        // interact with App
    });

    test("does something ELSE as expected", async () => {
        const {container} = renderWithRedux(<App />); //I DONT WANT THE STATE FROM PREVIOUS TEST
    });

});

我遇到的问题是第一个 &lt;App /&gt; 的状态“泄漏”到下一个测试中,我希望我的每个测试都是独立的。实现此目的的正确方法是什么?

这里是renderWithRedux的定义:

import React from "react";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from 'redux';
import {reducer, initialState} from "./store";
import thunkMiddleware from 'redux-thunk';
import { render } from '@testing-library/react';
import { Router } from 'react-router-dom'
import { createMemoryHistory } from 'history'

function renderWithRedux(
  ui,
  { initialState, store = createStore(reducer, initialState, applyMiddleware(thunkMiddleware)) } = {}
) {
  return {
    ...render(<Provider store={store}>{ui}</Provider>),
    store
  }
}

package.json:

{
  "dependencies": {
    "react": "^16.11.0",
    "react-dom": "^16.11.0",
    "react-redux": "^7.1.3",
    "react-router-dom": "^5.1.2",
    "react-scripts": "2.1.5",
    "redux": "^4.0.4",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^4.2.3",
    "@testing-library/react": "^9.3.2",
    "redux-mock-store": "^1.5.3",
    "typescript": "^3.7.2"
  }
}

【问题讨论】:

    标签: reactjs jestjs integration-testing react-testing-library


    【解决方案1】:

    这可以通过initialState 参数传递状态来完成,您的renderWithRedux 函数已经接受了该参数。有关使用 Redux 和 React 测试库的更多信息,Redux docs 有一个很好的概述 - 看看吧!

    此外,我们可以在此处删除asyncs,直到我们拥有awaiting 的内容,并且我们也可以删除describe 函数。正如 KCD 所说,“avoid nesting when you're testing”。

    import React from 'react';
    import { renderWithRedux } from '../testUtils';
    import App from '../components/App';
    
    test('does something as expected', () => {
        const { container } = renderWithRedux(<App />, {
            initialState: {
                superhero: 'Spiderman',
            },
        });
    });
    
    test('does something ELSE as expected', () => {
        const { container } = renderWithRedux(<App />, {
            initialState: {
                superhero: 'Wonder Woman',
            },
        });
    });
    
    

    至于使用cleanup,React Scripts 使用 Jest 作为其测试运行器。根据React Testing Library docs,Jest 自动使用 React 测试库的cleanup,因此在这种情况下无需添加该步骤!

    【讨论】:

      【解决方案2】:

      此问题已在 v9.0.0 中修复。来自docs

      请注意,如果您使用的测试框架支持 afterEach 全局变量(如 mocha、Jest 和 Jasmine),则此操作会自动完成。如果没有,您将需要在每次测试后进行手动清理。

      我在使用早期版本的@testing-library/react 时遇到了同样的问题,解决方案是使用cleanup

      import { render, cleanup } from '@testing-library/react'
      
      describe('...', () => {
        afterEach(cleanup)
      
        it('...', () => {
          // ...
        })
      })
      

      来自文档:

      在调用 render 时未能调用 cleanup 可能会导致内存泄漏和非“幂等”测试(这可能会导致在测试中难以调试错误)。

      同样,在 v9+ 中,这是自动完成的。

      【讨论】:

        【解决方案3】:

        您可以使用 jest 的 beforeEach 钩子每次都重新实例化组件。

        https://jestjs.io/docs/en/setup-teardown#repeating-setup-for-many-tests

        您的测试块如下所示。

        import React from "react";
        import { renderWithRedux } from "../testUtils";
        import App from "../components/App";
        
        describe("App", () => {
          let component;
        
          beforeEach(() => {
            component = <App />;
          });
          test("does something as expected", async () => {
            const { container } = renderWithRedux(component);
            // interact with App
          });
        
          test("does something ELSE as expected", async () => {
            const { container } = renderWithRedux(component);
          });
        });
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-22
          • 1970-01-01
          • 2020-08-18
          • 2021-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多