Библиотека тестирования: как рендерить один и тот же компонент несколько раз без сопряжения

Я использую 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
    });

});

Проблема, с которой я сталкиваюсь, заключается в том, что состояние первого <App /> «просачивается» в следующий тест, и я хочу, чтобы каждый из моих тестов был независимым. Каков правильный способ добиться этого?

Вот определение 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
  }
}

пакет.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"
  }
}

person emersonthis    schedule 09.12.2019    source источник


Ответы (3)


Этого можно добиться, передав состояние через аргумент initialState, который уже принимает ваша функция renderWithRedux. Дополнительную информацию об использовании Redux с библиотекой тестирования React можно найти в документах Redux. есть отличный обзор - проверить его!

Кроме того, мы можем удалить async здесь, пока у нас не будет чего-то, что мы await делаем, и мы, вероятно, также можем удалить функцию describe. Как говорит KCD, избегайте вложения при тестировании.

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, Jest использует React Testing Library cleanup автоматически, поэтому в этом случае нет необходимости добавлять этот шаг!

person josephemswiler    schedule 16.09.2020

Эта проблема исправлена ​​в v9.0.0. . Из документов:

Обратите внимание, что это делается автоматически, если используемая среда тестирования поддерживает глобальный параметр afterEach (например, mocha, Jest и Jasmine). Если нет, вам нужно будет выполнять ручную очистку после каждого теста.

Я столкнулся с той же проблемой с более ранней версией @testing-library/react, и решение заключалось в использовании cleanup:

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

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

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

Из документов:

Если не вызвать очистку при вызове рендеринга, это может привести к утечке памяти и тестам, которые не являются «идемпотентными» (что может привести к трудностям при отладке ошибок в ваших тестах).

Опять же, в v9+ это делается автоматически.

person jessepinho    schedule 29.01.2020

Вы можете использовать хук 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);
  });
});

person johnny peter    schedule 10.12.2019