Атрибут отключения кнопки не обновляется правильно, когда выполняются два рендеринга одного и того же компонента.

Я только начал использовать библиотеку тестирования реакции, поэтому я предполагаю, что это в конечном итоге связано с ошибкой пользователя, но я вижу следующее поведение, которое не имеет для меня смысла.

Для следующего тестового запуска в только что созданном приложении CRA с использованием jest-dom 3.0.0 и react-testing-library 5.4.4:


    import React from "react";
    import { render } from "react-testing-library";
    import "jest-dom/extend-expect";

    import Component from "./Component";

    describe("Verify UI state based on jobs", () => {
      it("mounts with no previous data", () => {
        const { getByTestId } = render(<Component data={[]} />);
        expect(getByTestId("refresh-button")).toBeDisabled();
      });

      it("mounts with previous data", () => {
        const { getByTestId } = render(<Component data={["hi"]} />);
        expect(getByTestId("refresh-button")).not.toBeDisabled();
      });
    });

    /*
    const Component = props => {
      return (
        <div>
          <button data-testid="refresh-button" disabled={props.data.length === 0}>
            Refresh
          </button>
        </div>
      );
    };
    */

Поскольку дела обстоят так, я получаю следующую ошибку:

Проверка состояния пользовательского интерфейса на основе заданий › монтирования с предыдущими данными

expect(element).not.toBeDisabled()

Received element is disabled:
  <button data-testid="refresh-button" disabled="" />

  13 |   it("mounts with previous data", async () => {
  14 |     const { getByTestId } = render(<Component data={["hi"]} />);
> 15 |     expect(getByTestId("refresh-button")).not.toBeDisabled();
     |                                               ^
  16 |   });
  17 | });
  18 |

  at Object.toBeDisabled (src/Component.test.js:15:47)

Однако, если я отключу первый тест, второй теперь проходит как надо. Если я переупорядочиваю вещи, первый тест всегда проходит, а второй всегда терпит неудачу, даже если первый тест — это тест «монтирования с предыдущими данными».

Не уверен, что это проблема в тестовой библиотеке, jest-dom или моем коде, но любые советы о том, как правильно построить эти тесты, будут оценены.


person robowen5mac    schedule 10.01.2019    source источник


Ответы (1)


В настоящее время в документах указано, что когда render вызывается "запросы из dom-testing-library автоматически возвращаются с их первым аргументом, привязанным к отображаемому контейнеру"< /а>.

Как оказалось, это ошибка в документации, поскольку запросы фактически привязаны к document.body, если container не передается в render (код here and здесь).

react-testing-library использует DOM, и если cleanup не вызывается между тестами, элементы DOM из более ранних тестов все еще будут там и будут включены в более поздние результаты запроса.

В этом случае оба элемента Component существуют в document.body во время второго теста, и, поскольку getByTestId запрашивает document.body, он находит их оба, а когда находит более одного, возвращает первое найденное.

Это означает, что Component из первого теста возвращается getByTestId во втором тесте, что приводит к сбою теста, поскольку первый компонент отключен.


Чтобы решить эту проблему, обязательно вызывайте cleanup после каждого теста, чтобы удалить все элементы DOM, которые были добавлены во время предыдущих тестов:

import React from "react";
import { render, cleanup } from "react-testing-library";
import "jest-dom/extend-expect";

afterEach(cleanup);  // clean up the DOM after each test

describe("Verify UI state based on jobs", () => {
  it("mounts with no previous data", () => {
    const { getByTestId } = render(<Component data={[]} />);
    expect(getByTestId("refresh-button")).toBeDisabled();  // SUCCESS
  });

  it("mounts with previous data", () => {
    const { getByTestId } = render(<Component data={["hi"]} />);
    expect(getByTestId("refresh-button")).not.toBeDisabled();  // SUCCESS
  });
});
person Brian Adams    schedule 11.01.2019
comment
Я создал запрос на включение, чтобы исправить ошибку. - person Brian Adams; 11.01.2019
comment
Обновление: создатель react-testing-library говорит, что привязка запросов к document.body является преднамеренной, поэтому ошибка только в документации. Я обновил свой ответ, чтобы отразить эту дополнительную информацию. - person Brian Adams; 11.01.2019
comment
Спасибо за помощь. Я упустил цель очистки и, честно говоря, более подробную документацию, в которой четко указано, что вам нужно запускать очистку между тестами. Моя вина в том, что я не вышел за пределы страницы GitHub, когда начал играть с вещами. - person robowen5mac; 11.01.2019