Как протестировать className с помощью библиотеки тестирования Jest и React

Я новичок в тестировании JavaScript и работаю с новой кодовой базой. Я хотел бы написать тест, который проверяет className в элементе. Я работаю с Jest и Библиотека тестирования React. Ниже у меня есть тест, который отображает кнопку на основе опоры variant. Он также содержит className, и я хотел бы это проверить.

it('Renders with a className equal to the variant', () => {
    const { container } = render(<Button variant = "default" />)
    expect(container.firstChild) // Check for className here
})

Я попытался найти в Google свойство вроде Enzyme с hasClass, но ничего не нашел. Как я могу решить эту проблему с помощью текущих библиотек (Библиотека тестирования React и Jest)?

Вам следует использовать Enzyme, именно по этой причине он предназначен для работы с шутками. Jest отлично подходит для тестирования функциональности, Enzyme для тестирования компонентов и рендеринга.

AnonymousSB 20.11.2018 10:56

Следуя комментарию @AnonymousSB, Enzyme отлично подходит, если вас больше интересует реализация тестирования, тогда как React Testing Library предназначена для тех, кто использует подход к тестированию, более ориентированный на поведение пользователя.

James B. Nall 14.07.2020 16:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
93
2
156 599
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Вы можете легко сделать это с помощью библиотеки react-testing-library.

Во-первых, вы должны понимать, что container или результат getByText и т. д. Являются просто узлами DOM. Вы можете взаимодействовать с ними так же, как в браузере.

Итак, если вы хотите знать, какой класс применяется к container.firstChild, вы можете просто сделать это, как этот container.firstChild.className.

Если вы прочитаете больше о className в MDN, вы увидите, что он возвращает все классов, примененных к вашему элементу, разделенных пробелом, то есть:

<div class = "foo">     => className === 'foo'
<div class = "foo bar"> => className === 'foo bar'

Это может быть не лучшим решением в зависимости от вашего случая. Не беспокойтесь, вы можете использовать другой API браузера, например classList.

expect(container.firstChild.classList.contains('foo')).toBe(true)

Вот и все! Не нужно изучать новый API, который работает только для тестов. Всё как в браузере.

Если проверка класса - это то, что вы часто делаете, вы можете упростить тесты, добавив шутка в свой проект.

Тогда тест станет:

expect(container.firstChild).toHaveClass('foo')

Есть множество других удобных методов, таких как toHaveStyle, которые могут вам помочь.


Кстати, react-testing-library - это подходящая утилита для тестирования JavaScript. У него много преимуществ перед другими библиотеками. Я рекомендую вам присоединиться к форум по спектру, если вы новичок в тестировании JavaScript.

Привет! Я вижу, что вы используете toBeTrue, но у меня почему-то есть TypeError: expect(...).toBeTrue is not a function. У меня последняя версия Jest. toHaveClass работает нормально!

Giesburts 20.11.2018 12:22

Моя беда, это toBe(true). Починил. Я использую toHaveClass, так проще

Giorgio Polvara - Gpx 20.11.2018 15:47

Извините, я так и не принял этот ответ. Это действительно было!

Giesburts 05.06.2019 19:00

@ GiorgioPolvara-Gpx Я все еще думаю, что это хакерский способ сделать это, когда библиотека не поддерживает метод getByClass.

Jaspreet Singh 16.07.2019 07:26

В библиотеке нет метода getByClass, потому что он хочет подтолкнуть вас к тестированию, как это сделал бы пользователь. Пользователи не видят классы. Но если по какой-то причине визуализированные классы - это то, что вы хотите протестировать, это способ сделать это.

Giorgio Polvara - Gpx 16.07.2019 10:54

@ GiorgioPolvara-Gpx, как бы вы протестировали несколько классов, например foo bar? Я пытался добавить expect(container.firstChild.classList.contains('foo bar')).toBe(true), но это не помогло, если я что-то не упустил.

medev21 22.02.2020 00:57

Вам нужно сделать это в два этапа, один для foo, а другой для bar.

Giorgio Polvara - Gpx 25.02.2020 15:18

как ни странно после обновления expect(container.firstChild).toHaveClass('foo') больше не работает в некоторых моих тестах, expect(container.firstChild.classList.contains('foo')).toBe(‌​true) да

AlainIb 04.12.2020 12:16

Вам необходимо понять философию реагировать-тестирование-библиотека, чтобы понять, что вы можете сделать, а что нет;

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

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

Поэтому вместо поиска элемента по тому, что пользователь не может видеть, и тому, что может измениться в любое время, просто попробуйте выполнить поиск, используя что-то, что пользователь может видеть, например текст, метку или что-то, что останется постоянным в жизненном цикле элемента. как идентификатор данных.

Итак, чтобы ответить на ваш вопрос, не рекомендуется тестировать имя класса, и, следовательно, вы не можете сделать это с помощью реагировать-тестирование-библиотека. Попробуйте использовать другие тестовые библиотеки, такие как Фермент или Утилиты для тестирования React-Dom.

Я видел этот ответ, данный ранее здесь и от авторов react-testing-library. Я никогда этого не понимал. «classNames» - это, по определению, то, что увидят пользователи. Они находятся на переднем крае взаимодействия с пользователем. Было бы неплохо узнать, был ли применен к элементу жизненно важный помощник класса, чтобы этот элемент, например, стал видимым.

mrbinky3000 26.11.2019 19:10

В дополнение к вышесказанному, некоторые библиотеки css, такие как семантический пользовательский интерфейс, делают модель DOM более читаемой, просматривая ее классы CSS. Итак, у вас есть что-то вроде <div class = "title"> или <div class = "step"> и т. д. Без запроса по классу его сложно утверждать при использовании сематического пользовательского интерфейса.

sethu 16.01.2020 21:54

@ mrbinky3000 вы можете проверить наличие / отсутствие класса в элементе, и это очень хорошо и хорошо поддерживается RTL при использовании с шутка. Что такое муравейник, так это поиск элемента с помощью className в тестах.

kasongoyo 17.01.2020 10:03

@ mrbinky3000 Пользователи не могут видеть имена классов. Хотя на практике не всегда можно что-то протестировать без тестирования деталей реализации.

dan-klasson 13.05.2020 15:14

Запутать prod cod с data-testid для меня больше, чем использовать атрибут class для просмотра отрисованного кода. Не говоря уже о том, что у вас действительно нет выбора, если вы хотите проверить рендеринг стороннего кода. Если только вы не хотите все высмеивать. Которые о людях тоже снимают ролики, которых делать не надо. Я считаю, что это великая философия, а не практический подход.

bmolnar 24.12.2020 12:27

Авторы на самом деле поняли, что эти принципы не могут применяться для всех случаев использования (в моем случае это было тестирование на наличие счетчика / загрузчика во время сетевого запроса), и поэтому они написали: "In the spirit of the guiding principles, it is recommended to use this (data-testid) only after the other queries don't work for your use case. Using data-testid attributes do not resemble how your software is used and should be avoided if possible. That said, they are way better than querying based on DOM structure or styling css class names." Думаю, это зависит от вас!

kawerewagaba 20.06.2021 16:03

Если вас больше всего беспокоит то, что ваш код продукта содержит данные-тести, их всегда можно удалить во время сборки. Пример: babel-plugin-jsx-remove-data-test-id

Rui Marques 24.09.2021 12:44

Вы можете использовать настраиваемые сопоставители testing-library / jest-dom.

The @testing-library/jest-dom library provides a set of custom jest matchers that you can use to extend jest. These will make your tests more declarative, clear to read and to maintain.

https://github.com/testing-library/jest-dom#tohaveclass

it('Renders with a className equal to the variant', () => {
    const { container } = render(<Button variant = "default" />)

    expect(container.firstChild).toHaveClass('class-you-are-testing') 
})

Это можно настроить глобально в файле setupTest.js.

import '@testing-library/jest-dom/extend-expect';
import 'jest-axe/extend-expect';
// etc

Библиотека предоставляет доступ к обычным селекторам DOM, поэтому мы также можем просто сделать это:

it('Renders with a className equal to the variant', () => {
    const { container } = render(<Button variant = "default" />)
    expect(container.getElementsByClassName('default').length).toBe(1);
});

Должен быть принятый ответ.

Reactgular 11.10.2021 14:49
    // Link.react.test.js
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import App from './../../src/App'
describe('React', () => {
  it('className', () => {
    const renderer = new ShallowRenderer();
    renderer.render(<App />);
    const result = renderer.getRenderOutput();
    expect(result.props.className.split(' ').includes('welcome-framework')).toBe(true);
  });
});

Проще говоря, вы должны использовать toHaveClass от Jest Нет необходимости добавлять дополнительную логику

it('Renders with a className equal to the variant', () => {
    const { container } = render(<Button variant = "default" />)
    expect(container.firstChild).toHaveClass(add you className);
//You Can Also You Screen Instead Of Using Container Container Not Recommended To Use As Documentation Said
    expect(screen.getByRole('button')).toHaveClass(add you className)
})

Другие вопросы по теме