Как вы проверяете отсутствие элемента с помощью библиотеки jest и react-testing-library?

У меня есть библиотека компонентов, в которой я пишу модульные тесты для использования Jest и react-testing-library. Основываясь на определенных свойствах или событиях, я хочу убедиться, что определенные элементы не отображаются.

getByText, getByTestId и т. Д. Выдают ошибку в react-testing-library, если элемент не найден, что приводит к сбою теста до запуска функции expect.

Как вы тестируете что-то, чего не существует в шутке, с помощью библиотеки react-testing-library?


person SomethingOn    schedule 12.10.2018    source источник


Ответы (6)


Из Документы библиотеки тестирования DOM - появление и исчезновение

Утверждающие элементы отсутствуют

Стандартные getBy методы выдают ошибку, когда не могут найти элемент, поэтому, если вы хотите заявить, что элемент не присутствует в DOM, вы можете вместо этого использовать queryBy API:

const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

Версия API queryAll возвращает массив совпадающих узлов. Длина массива может быть полезна для утверждений после добавления или удаления элементов из DOM.

const submitButtons = screen.queryAllByText('submit')
expect(submitButtons).toHaveLength(2) // expect 2 elements

not.toBeInTheDocument

Библиотека утилит jest-dom предоставляет средство сопоставления .toBeInTheDocument(), которое можно использовать для подтверждения того, что элемент находится в теле документа или нет. Это может быть более значимым, чем утверждение результата запроса null.

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()
person kentcdodds    schedule 12.10.2018
comment
Мои плохие kentcdodds, спасибо. Я использовал getByTestId и получил ту же ошибку. И я не проверял FAQ, извините. Отличная библиотека! Можете ли вы изменить свой ответ, включив в него `.toBeNull (); - person SomethingOn; 12.10.2018
comment
Я считаю, что ссылка выше была предназначена для указания на документы библиотеки тестирования-реакции < / а> - person pbre; 04.01.2019
comment
Новый сайт документации был опубликован несколько дней назад. Я должен был использовать более постоянную ссылку. Спасибо за обновление @pbre! - person kentcdodds; 04.01.2019
comment
и queryByText для тех, кто хочет эквивалент getByText, который является нулевым. - person S..; 03.08.2019
comment
Я действительно не хочу устанавливать тонну идентификаторов тестов только для проверки отсутствия определенных элементов в определенных состояниях, это как бы идет вразрез с рекомендациями библиотеки тестирования, не так ли? - person Hylle; 23.04.2020
comment
Согласовано. Вы можете использовать вариант запроса * любого из запросов. testing-library .com / docs / dom-testing-library / api-query. - person kentcdodds; 23.04.2020
comment
Возможно, стоит отметить, что это работает, когда queryBy.. или getBy.. деструктурируются из метода рендеринга. Я использовал screen.get.. методы, и это выдает ошибку. - person Sam; 29.04.2020
comment
@Sam, убедитесь, что у вас последняя версия библиотеки тестирования. screen API теперь рекомендуется вместо деструктуризации. - person kentcdodds; 29.04.2020
comment
not.toBeInTheDocument отсутствует в @react-native-community/testing-library - person Dimitri Kopriwa; 17.02.2021

Используйте queryBy / queryAllBy.

Как вы говорите, getBy* и getAllBy* выдают ошибку, если ничего не найдено.

Однако эквивалентные методы queryBy* и queryAllBy* вместо этого возвращают null или []:

queryBy

queryBy* запросы возвращают первый совпадающий узел для запроса и возвращают null, если ни один элемент не соответствует. Это полезно для утверждения элемента, которого нет. Это срабатывает, если найдено более одного совпадения (вместо этого используйте queryAllBy).

queryAllBy queryAllBy* запросы возвращают массив всех совпадающих узлов для запроса и возвращают пустой массив ([]), если ни один элемент не соответствует.

https://testing-library.com/docs/dom-testing-library/api-queries#queryby

Таким образом, для конкретных двух, которые вы упомянули, вы вместо этого использовали бы queryByText и queryByTestId, но они работают для всех запросов, а не только для этих двух.

person Sam    schedule 04.11.2019
comment
Это лучше, чем принятый ответ. Этот API новее? - person RubbelDieKatz; 25.11.2019
comment
Спасибо за добрые слова! Это в основном та же функциональность, что и принятый ответ, поэтому я не думаю, что это более новый API (но я мог бы неправильный). Единственная реальная разница между этим ответом и принятым состоит в том, что в принятом ответе говорится, что существует только метод, который делает это (queryByTestId), хотя на самом деле существует два полных набора методов, из которых queryByTestId является одним из конкретных примеров. - person Sam; 25.11.2019
comment
Спасибо, я бы предпочел это, чем установка тестовых идентификаторов - person Hylle; 23.04.2020
comment
Спасибо за подробное объяснение. Это такая тонкая разница, что я не заметил ее, несмотря на то, что посмотрел на их пример здесь: github.com/testing-library/jest-dom#tobeinthedocument: лицо-ладонь: - person St. John; 02.02.2021

Вы должны использовать 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();
  });
});
person Valentin Garreau    schedule 14.05.2019

getBy * выдает ошибку, когда не находит элементы, поэтому вы можете проверить это

expect(() => getByText('your text')).toThrow('Unable to find an element');
person Gabriel Vasile    schedule 18.06.2020
comment
Это может быть довольно чревато ошибками. Выбросы ошибок используются для целей отладки, а не для проверки. - person Milen Gardev; 06.01.2021

Вы можете использовать react-native-testing-library "getAllByType", а затем проверить, является ли компонент нулевым. Имеет то преимущество, что не нужно устанавливать TestID, также должен работать со сторонними компонентами.

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });
person Andy Rich    schedule 09.10.2019
comment
Этот вид нарушает предпосылку отсутствия деталей реализации (таких как имя компонента) в тесте. - person RubbelDieKatz; 25.11.2019

Другое решение: вы также можете использовать блок 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();
}
person Bassem    schedule 22.01.2021