您如何使用Jest和react-testing-library测试元素的不存在?


102

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

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

您如何使用react-testing-library测试是否在笑话中不存在?

Answers:


214

来自DOM Testing-library Docs-外观和消失

断言元素不存在

标准getBy方法找不到元素时会引发错误,因此,如果要断言DOM中存在元素,则可以改用queryByAPI:

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

queryAllAPI的版本返回匹配节点的数组。在将元素添加到DOM中或从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()

4
不好意思,谢谢。我用过,getByTestId并得到相同的错误。而且,我没有检查FAQ,抱歉。很棒的图书馆!您可以修改答案以包含`.toBeNull();吗?
SomethingOn

3
我相信上面的链接旨在指向react-testing-library文档
pbre19,19年

2
新的文档站点已于几天前发布。我应该使用一个更永久的链接。感谢更新@pbre!
kentcdodds


6
queryByText对于那些谁想要就相当于getByText是空安全
秒。

24

使用queryBy/ queryAllBy

正如你所说,getBy*getAllBy*如果没有找到引发错误。

但是,等效的方法queryBy*queryAllBy*而是返回null[]

查询

queryBy*查询返回查询的第一个匹配节点,null如果没有元素匹配,则返回。这对于声明不存在的元素很有用。如果找到多个匹配项,则抛出该异常(改为使用queryAllBy)。

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

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

因此,对于您提到的特定两个,您将改为使用queryByTextqueryByTestId,但它们适用于所有查询,而不仅仅是这两个。


2
这比公认的答案更好。这个API是新的吗?
RubbelDieKatz

1
感谢您的客气话!这基本上与接受的答案具有相同的功能,所以我认为它不是较新的API(但是我可能错了)。这个答案和被接受的答案之间唯一真正的区别是,被接受的答案表示只有一种方法可以做到这一点(queryByTestId),而实际上有两套完整的方法,其中queryByTestId一个是特定的示例。
山姆

谢谢,我更喜欢此方法,而不是设置测试ID
Hylle

14

您必须使用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();
  });
});


2

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

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });

这种违反的前提是测试中没有实现细节(例如组件名称)。
RubbelDieKatz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.