Библиотека тестирования React — вложенные компоненты препятствуют правильному отображению родительских компонентов

#reactjs #react-testing-library

#reactjs #react-testing-library

Вопрос:

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

Компонент:

 import React from "react";

import Confirm from "components/Confirm";

interface Props {
  error?: string;
}

function ErrorPage({ error }: Props): JSX.Element {
  const renderErrors = () => {
    return <>{error amp;amp; <p>{error}</p>}</>;
  };

  return (
    <Confirm
      title="Error"
      action=""
    >
      <p>An error occurred while processing the request.</p>
      {renderErrors()}
    </Confirm>
  );
}

export default ErrorPage;
 

Тест:

 import React from "react";
import { render, screen } from '@testing-library/react';
import ErrorPage from "./ErrorPage";

describe("ErrorPage", () => {
  const message = "There was an error";
  it("renders successfully", () => {
    render(<ErrorPage error={message} />);
  });

  it("displays the error",() => {
    const { getByText } = render(<ErrorPage error={message} />);
    screen.debug();
    expect(getByText("There was an error")).toBeInTheDocument();
  });
});

 

Мой первый тест пройден, мой второй тест провален.

Вывод из screen.debug()

 <body>
  <div />
</body>
 

Ошибка второго теста:

     TestingLibraryElementError: Unable to find an element with the text: There was an error. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

    <body>
      <div />
    </body>

      12 |     const { getByText } = render(<ErrorPage error={message} />);
      13 |     screen.debug();
    > 14 |     expect(getByText("There was an error")).toBeInTheDocument();
         |            ^
      15 |   });
      16 | });
      17 |

 

Когда я удаляю вложенный компонент <Confirm /> и заменяю его на простой <div></div> , тесты проходят.

 import React from "react";

interface Props {
  error?: string;
}

function ErrorPage({ error }: Props): JSX.Element {
  const renderErrors = () => {
    return <>{error amp;amp; <p>{error}</p>}</>;
  };

  return (
    <div
    >
      <p>An error occurred while processing the request.</p>
      {renderErrors()}
    </div>
  );
}

export default ErrorPage;
 

Чего мне здесь не хватает? Нужно ли мне как-то заглушить <Confirm/> компонент?

Комментарии:

1. Я предполагаю <Confirm> , что он не сразу отображает своих дочерних элементов, и в этом есть какая-то логика? Одним из вариантов было бы отключить этот компонент, чтобы избежать необходимости иметь дело с дополнительной логикой и перейти к модульному тестированию. Другим вариантом было бы включить шаги, необходимые для рендеринга дочерних элементов, работая больше как интеграционный тест.

2. Спасибо за ваш вклад @juliomalves — я бы предпочел отключить компонент. Есть какие-нибудь идеи, как это сделать?