У меня есть библиотека компонентов, в которой я пишу модульные тесты для использования Jest и react-testing-library. Основываясь на определенных свойствах или событиях, я хочу убедиться, что определенные элементы не отображаются.
getByText, getByTestId и т. д. Выдают ошибку в react-testing-library, если элемент не найден, что приводит к сбою теста до срабатывания функции expect.
Как вы тестируете что-то, чего не существует в шутке, с помощью библиотеки react-testing-library?





От Документы библиотеки тестирования DOM - появление и исчезновение
Asserting elements are not present
The standard
getBymethods throw an error when they can't find an element, so if you want to make an assertion that an element is not present in the DOM, you can usequeryByAPIs instead:const submitButton = screen.queryByText('submit') expect(submitButton).toBeNull() // it doesn't existThe
queryAllAPIs version return an array of matching nodes. The length of the array can be useful for assertions after elements are added or removed from the DOM.const submitButtons = screen.queryAllByText('submit') expect(submitButtons).toHaveLength(2) // expect 2 elements
not.toBeInTheDocumentThe
jest-domutility library provides the.toBeInTheDocument()matcher, which can be used to assert that an element is in the body of the document, or not. This can be more meaningful than asserting a query result isnull.import '@testing-library/jest-dom/extend-expect' // use `queryBy` to avoid throwing an error with `getBy` const submitButton = screen.queryByText('submit') expect(submitButton).not.toBeInTheDocument()
Я считаю, что ссылка выше должна указывать на реагировать-тестирование-библиотека документов
Новый сайт документации был опубликован несколько дней назад. Я должен был использовать более постоянную ссылку. Спасибо за обновление @pbre!
Еще один удобный ресурс: testing-library.com/docs/react-testing-library/cheatsheet
и queryByText для тех, кому нужен эквивалент getByText, который является нулевым.
Я действительно не хочу устанавливать тонну идентификаторов тестов только для проверки отсутствия определенных элементов в определенных состояниях, это как бы идет вразрез с рекомендациями библиотеки тестирования, не так ли?
Согласовано. Вы можете использовать вариант запроса * любого из запросов.
Возможно, стоит отметить, что это работает, когда queryBy.. или getBy.. деструктурируются с помощью метода рендеринга. Я использовал методы screen.get.., и это выдает ошибку.
@Sam, убедитесь, что у вас последняя версия библиотеки тестирования. screen API теперь рекомендуется вместо деструктуризации.
not.toBeInTheDocument отсутствует в @react-native-community/testing-librarytoBeInTheDocument является частью jest-dom, а не RTL
Вы должны использовать queryByTestId вместо getByTestId.
Вот пример кода, в котором я хочу проверить, не существует ли компонента с идентификатором «автомобиль».
describe('And there is no car', () => {
it('Should not display car mark', () => {
const props = {
...defaultProps,
base: null,
}
const { queryByTestId } = render(
<IntlProvider locale = "fr" messages = {fr}>
<CarContainer{...props} />
</IntlProvider>,
);
expect(queryByTestId(/car/)).toBeNull();
});
});
Вы можете использовать react-native-testing-library "getAllByType", а затем проверить, является ли компонент нулевым. Имеет то преимущество, что не нужно устанавливать TestID, также должен работать со сторонними компонентами.
it('should contain Customer component', () => {
const component = render(<Details/>);
const customerComponent = component.getAllByType(Customer);
expect(customerComponent).not.toBeNull();
});
Этот вид нарушает предпосылку отсутствия деталей реализации (таких как имя компонента) в тесте.
Используйте queryBy / queryAllBy.
Как вы говорите, getBy* и getAllBy* выдают ошибку, если ничего не найдено.
Однако эквивалентные методы queryBy* и queryAllBy* вместо этого возвращают null или []:
queryBy
queryBy*queries return the first matching node for a query, and returnnullif no elements match. This is useful for asserting an element that is not present. This throws if more than one match is found (use queryAllBy instead).queryAllBy
queryAllBy*queries return an array of all matching nodes for a query, and return an empty array ([]) if no elements match.
https://testing-library.com/docs/dom-testing-library/api-queries#queryby
Итак, для конкретных двух, которые вы упомянули, вы вместо этого использовали бы queryByText и queryByTestId, но они работают для всех запросов, а не только для этих двух.
Это лучше, чем принятый ответ. Этот API новее?
Спасибо за добрые слова! Это в основном та же функциональность, что и принятый ответ, поэтому я не думаю, что это более новый API (но я могу ошибаться). Единственная реальная разница между этим ответом и принятым состоит в том, что в принятом ответе говорится, что есть только метод, который делает это (queryByTestId), хотя на самом деле существует два полных набора методов, из которых queryByTestId является одним из конкретных примеров.
Спасибо, я бы предпочел это, чем установка тестовых идентификаторов
Спасибо за подробное объяснение. Это такая тонкая разница, что я не заметил ее, несмотря на то, что посмотрел на их пример здесь: github.com/testing-library/jest-dom#tobeinthedocument: face-palm:
getBy * выдает ошибку, когда не находит элементы, поэтому вы можете проверить это
expect(() => getByText('your text')).toThrow('Unable to find an element');
Это может быть довольно чревато ошибками. Выбросы ошибок используются для целей отладки, а не для проверки.
Другое решение: вы также можете использовать блок try/catch
expect.assertions(1)
try {
// if the element is found, the following expect will fail the test
expect(getByTestId('your-test-id')).not.toBeVisible();
} catch (error) {
// otherwise, the expect will throw, and the following expect will pass the test
expect(true).toBeTruthy();
}
const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist
expect(submitButton).not.toBeNull() // it exist
Мои плохие kentcdodds, спасибо. Я использовал
getByTestIdи получил ту же ошибку. И я не проверял FAQ, извините. Отличная библиотека! Можете ли вы изменить свой ответ, включив в него `.toBeNull ();