测试库:如何多次渲染同一组件而无需耦合

时间:2019-12-09 00:17:26

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

我正在通过Jest使用React Testing Library来测试我的React / Redux应用。

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

像这样...

getchar()

我遇到的问题是,第一个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 }); }); 的状态正在“泄漏”到下一个测试中,并且我希望每个测试都独立。什么是完成此任务的正确方法?

这是<App />的定义:

renderWithRedux

package.json:

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
  }
}

3 个答案:

答案 0 :(得分:1)

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

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

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

import { render, cleanup } from '@testing-library/react'

describe('...', () => {
  afterEach(cleanup)

  it('...', () => {
    // ...
  })
})

从文档中

调用render时未能调用清除操作可能会导致内存泄漏,并且测试不是“幂等的”(这可能导致难以调试测试中的错误)。

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

答案 1 :(得分:1)

这可以通过initialState函数已经接受的renderWithRedux参数传递状态来完成。有关将Redux与React Testing库一起使用的更多信息,Redux docs进行了概述-请查看!

此外,我们可以在这里删除async,直到我们拥有await的东西为止,并且我们也可能会删除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作为其测试运行器。根据{{​​3}},Jest自动使用React Testing库的cleanup,因此在这种情况下无需添加该步骤!

答案 2 :(得分:0)

您可以每次使用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);
  });
});