Проверка дочерних элементов передаваемых в мок React компонента

от автора

В преддверии старта курса «Автоматизация тестирования на JavaScript» продолжаем публиковать перевод серии полезных статей.


Это третья часть из серии о тестировании с React. В прошлой части мы рассмотрели базовый формат моков React компонентов.

Еще одна вещь, которую вы можете сделать с помощью моков, — это проверить, правильные ли дочерние элементы были переданы. Вот собственно на это мы сейчас и посмотрим.

Все образцы кода для этой статьи доступны в этом репозитории.

dirv / mocking-react-components

Представьте, что мы хотим вставить форму подписки на рассылку внутри PostContent. Мы можем сделать это, передав ему дочерние элементы.

Вот обновленный компонент BlogPage:

export const BlogPage = ({ url }) => {    const id = getPostIdFromUrl(url)    const handleSignUp = () => {     // …   }    return (     <PostContent id={id}>       <input type="email" placeholder="Sign up to my mailing list!" />       <button onClick={handleSignUp}>Sign up</button>     </PostContent>   ) }

Важно то, что наши тесты BlogPage не должно волновать то, что PostContent делает с дочерними элементами. Они должны просто позаботиться о том, чтобы они ему были переданы.

Мы могли бы проверить это, вытащив пропс children из записи .mock.calls и затем отрендерив его с помощью render. Другими словами, рассматривать его как пропс для рендеринга.

Но есть более простой способ — заставить мок компонент отрисовывать его children:

jest.mock("../src/PostContent", () => ({   PostContent: jest.fn(({ children }) => (     <div data-testid="PostContent">{children}</div>   )) }))

Теперь мы можем написать тест, который проверяет, была ли button отрисована как дочерний элемент PostContent:

it("renders the mailing list sign up button as a child of PostContent", () => {   render(<BlogPage url="http://example.com/blog/my-web-page" />)    const postContentElement = screen.getByTestId("PostContent")    const button = screen.queryByRole(     "button", { name: "Sign up" })    expect(postContentElement).toContainElement(button) })

Тот же метод можно повторить и для поля input

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

expect(PostContent).toHaveBeenCalledWith(     { id: postId },     expect.anything())

Он фейлится, потому что внезапно у нас оказывается еще и пропс children, который мы совсем не ожидали в рамках этого теста.

Мы исправим это с помощью expect.objectContain.

Используйте expect.objectContain для локализации ваших тестов

Часто бывает полезно иметь несколько модульных тестов для одного вызова мока компонента! Обычно я начинаю с одного теста со всеми указанными пропсами. Но для любых достаточно сложных значений пропсов может быть гораздо полезнее разбить их на отдельные тесты с хорошим описанием. Пропс children — как раз такой случай: наш тест, который проверяет, что мы передаем правильный ID, не зависит от чего-либо, связанного с отображаемым содержимым.

Мы можем избежать тестирования content, используя expect.objectContain в нашем ожидании:

 expect(PostContent).toHaveBeenCalledWith(     expect.objectContaining({ id: postId }),     expect.anything())

Подытожим

Итак, что мы узнали на данный момент?

  • Чтобы протестировать дочерние элементы, переданные в моки, измените мок компонент на `jest.fn (({children}) = {children})

  • Используйте toContainElement из пакета матчеров jest-dom, чтобы проверить, отображаются ли компоненты как дочерние элементы вашего мок компонента.

  • Используйте expect.objectContain для написания модульных тестов, которые не будут ломаться при изменении ваших пропсов.

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

В четвертой части мы будем тестировать несколько отрисованных экземпляров одного и того же мок компонента.


Приглашаем вас записаться на бесплатный демо-урок по теме: «Основы puppeteer».


Читать ещё:

ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/524662/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *