211

我有一个组件库,我正在为使用 Jest 和 react-testing-library 编写单元测试。基于某些道具或事件,我想验证某些元素没有被渲染。

getByText, getByTestId, 等如果在函数触发react-testing-library之前未找到元素导致测试失败,则会抛出错误。expect

你如何使用 react-testing-library 测试不存在的东西?

4

9 回答 9

427

来自DOM Testing-library Docs - Appearance and Disappearance

断言元素不存在

标准getBy方法在找不到元素时会抛出错误,因此如果您想断言元素存在于 DOM 中,则可以使用queryByAPI:

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()
于 2018-10-12T16:02:34.987 回答
48

使用queryBy/ queryAllBy

正如你所说,如果没有找到getBy*getAllBy*则抛出错误。

但是,等效的方法queryBy*andqueryAllBy*而是返回nullor []

查询依据

queryBy*查询返回查询的第一个匹配节点,null如果没有元素匹配则返回。这对于断言不存在的元素很有用。如果找到多个匹配项,则会抛出此错误(改用 queryAllBy)。

queryAllBy queryAllBy*查询返回一个查询的所有匹配节点的数组,[]如果没有元素匹配,则返回一个空数组 ( )。

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

因此,对于您提到的特定两个,您将改用queryByTextand queryByTestId,但这些适用于所有查询,而不仅仅是这两个。

于 2019-11-04T12:27:29.883 回答
27

getBy* 在找不到元素时会引发错误,因此您可以检查一下

expect(() => getByText('your text')).toThrow('Unable to find an element');
于 2020-06-18T10:50:52.997 回答
20

您必须使用 queryByTestId 而不是 getByTestId。

这是一个代码示例,我想测试具有“汽车”ID 的组件是否不存在。

 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();
  });
});
于 2019-05-14T13:07:58.040 回答
7
const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

expect(submitButton).not.toBeNull() // it exist
于 2021-05-24T00:26:03.103 回答
3

为我解决了(如果你想使用 getByTestId):

expect(() => getByTestId('time-label')).toThrow()
于 2021-10-18T13:38:11.923 回答
3

Another solution: you could also use a try/catch block

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();
}
于 2021-01-22T16:02:10.203 回答
2

您可以使用 react-native-testing-library "getAllByType" 然后检查组件是否为空。具有不必设置TestID的优点,也应该与第三方组件一起使用

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });
于 2019-10-09T15:10:25.353 回答
0

我最近写了一个方法来检查一个笑话黄瓜项目的元素可见性。

希望它是有用的。

public async checknotVisibility(page:Page,location:string) :Promise<void> 
{
    const element = await page.waitForSelector(location);
    expect(element).not.toBe(location); 
}
于 2022-02-08T15:58:33.097 回答