Я новичок в тестировании 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)?
Следуя комментарию @AnonymousSB, Enzyme отлично подходит, если вас больше интересует реализация тестирования, тогда как React Testing Library предназначена для тех, кто использует подход к тестированию, более ориентированный на поведение пользователя.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете легко сделать это с помощью библиотеки 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 работает нормально!
Моя беда, это toBe(true). Починил. Я использую toHaveClass, так проще
Извините, я так и не принял этот ответ. Это действительно было!
@ GiorgioPolvara-Gpx Я все еще думаю, что это хакерский способ сделать это, когда библиотека не поддерживает метод getByClass.
В библиотеке нет метода getByClass, потому что он хочет подтолкнуть вас к тестированию, как это сделал бы пользователь. Пользователи не видят классы. Но если по какой-то причине визуализированные классы - это то, что вы хотите протестировать, это способ сделать это.
@ GiorgioPolvara-Gpx, как бы вы протестировали несколько классов, например foo bar? Я пытался добавить expect(container.firstChild.classList.contains('foo bar')).toBe(true), но это не помогло, если я что-то не упустил.
Вам нужно сделать это в два этапа, один для foo, а другой для bar.
как ни странно после обновления expect(container.firstChild).toHaveClass('foo') больше не работает в некоторых моих тестах, expect(container.firstChild.classList.contains('foo')).toBe(true) да
Вам необходимо понять философию реагировать-тестирование-библиотека, чтобы понять, что вы можете сделать, а что нет;
Цель реагировать-тестирование-библиотека - избежать включения в тесты деталей реализации ваших компонентов и сосредоточиться на написании тестов, дающих вам уверенность, для которой они предназначены.
Таким образом, запрос элемента по имени класса не согласуется с философией реагировать-тестирование-библиотека, поскольку он включает детали реализации. Имя класса - это фактическая деталь реализации элемента, которую не увидит конечный пользователь, и оно может быть изменено в любой момент жизненного цикла элемента.
Поэтому вместо поиска элемента по тому, что пользователь не может видеть, и тому, что может измениться в любое время, просто попробуйте выполнить поиск, используя что-то, что пользователь может видеть, например текст, метку или что-то, что останется постоянным в жизненном цикле элемента. как идентификатор данных.
Итак, чтобы ответить на ваш вопрос, не рекомендуется тестировать имя класса, и, следовательно, вы не можете сделать это с помощью реагировать-тестирование-библиотека. Попробуйте использовать другие тестовые библиотеки, такие как Фермент или Утилиты для тестирования React-Dom.
Я видел этот ответ, данный ранее здесь и от авторов react-testing-library. Я никогда этого не понимал. «classNames» - это, по определению, то, что увидят пользователи. Они находятся на переднем крае взаимодействия с пользователем. Было бы неплохо узнать, был ли применен к элементу жизненно важный помощник класса, чтобы этот элемент, например, стал видимым.
В дополнение к вышесказанному, некоторые библиотеки css, такие как семантический пользовательский интерфейс, делают модель DOM более читаемой, просматривая ее классы CSS. Итак, у вас есть что-то вроде <div class = "title"> или <div class = "step"> и т. д. Без запроса по классу его сложно утверждать при использовании сематического пользовательского интерфейса.
@ mrbinky3000 вы можете проверить наличие / отсутствие класса в элементе, и это очень хорошо и хорошо поддерживается RTL при использовании с шутка. Что такое муравейник, так это поиск элемента с помощью className в тестах.
@ mrbinky3000 Пользователи не могут видеть имена классов. Хотя на практике не всегда можно что-то протестировать без тестирования деталей реализации.
Запутать prod cod с data-testid для меня больше, чем использовать атрибут class для просмотра отрисованного кода. Не говоря уже о том, что у вас действительно нет выбора, если вы хотите проверить рендеринг стороннего кода. Если только вы не хотите все высмеивать. Которые о людях тоже снимают ролики, которых делать не надо. Я считаю, что это великая философия, а не практический подход.
Авторы на самом деле поняли, что эти принципы не могут применяться для всех случаев использования (в моем случае это было тестирование на наличие счетчика / загрузчика во время сетевого запроса), и поэтому они написали: "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." Думаю, это зависит от вас!
Если вас больше всего беспокоит то, что ваш код продукта содержит данные-тести, их всегда можно удалить во время сборки. Пример: babel-plugin-jsx-remove-data-test-id
Вы можете использовать настраиваемые сопоставители 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);
});
Должен быть принятый ответ.
// 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)
})
Вам следует использовать Enzyme, именно по этой причине он предназначен для работы с шутками. Jest отлично подходит для тестирования функциональности, Enzyme для тестирования компонентов и рендеринга.