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

Som*_*gOn 36 reactjs jestjs react-testing-library

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

getByText,getByTestId等扔在错误react-testing-library如果未找到该元素,导致测试的前失效expect功能火灾.

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

ken*_*dds 76

DOM测试 - 图书馆文档 - 外观和消失

如果我想验证元素不存在怎么办?

您通常可以使用getByTestId实用程序访问呈现的元素.但是,如果找不到该元素,该函数将抛出错误.如果你想专门测试缺少一个元素,那么你应该使用queryByTestId实用程序,如果找到则返回该元素,否则返回null.

expect(queryByTestId('thing-that-does-not-exist')).toBeNull()
Run Code Online (Sandbox Code Playgroud)

  • 我的坏kentcdodds,谢谢.我使用`getByTestId`并得到了同样的错误.并且,我没有查看常见问题解答,抱歉.好图书馆!你可以修改你的答案,包括`.toBeNull(); (2认同)
  • 我相信上面的链接是指[react-testing-library docs](https://testing-library.com/docs/react-testing-library/faq) (2认同)
  • 几天前发布了新的文档站点。我应该使用更永久的链接。感谢更新@pbre! (2认同)
  • 另一个方便的资源:https://testing-library.com/docs/react-testing-library/cheatsheet (2认同)
  • 和`queryByText`,用于那些想要与`getByText`等效的安全的人 (2认同)

n1k*_*oza 54

希望这会有所帮助

该表显示了函数错误的原因/时间

哪些函数是异步的

什么是函数的返回语句

在此输入图像描述


Sam*_*Sam 40

使用queryBy/ queryAllBy

正如你所说,如果什么也没找到getBy*,就会getAllBy*抛出一个错误。

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

查询方式

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

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

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

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

  • 这比接受的答案要好得多。这个API比较新吗? (3认同)
  • 谢谢你的详细解释。这是一个如此微妙的差异,尽管在这里查看了他们的示例,但我没有看到它:https://github.com/testing-library/jest-dom#tobeinthedocument :face-palm: (3认同)

小智 32

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

expect(submitButton).not.toBeNull() // it exist
Run Code Online (Sandbox Code Playgroud)


mat*_*0ss 25

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

expect(() => getByTestId('time-label')).toThrow()
Run Code Online (Sandbox Code Playgroud)


Val*_*eau 17

您必须使用 queryByTestId 而不是 getByTestId。

这是一个代码示例,我想在其中测试具有“car” 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();
  });
});
Run Code Online (Sandbox Code Playgroud)


Gab*_*ile 16

getBy* 在找不到元素时抛出错误,因此您可以检查它

expect(() => getByText('your text')).toThrow('Unable to find an element');
Run Code Online (Sandbox Code Playgroud)

  • 这可能很容易出错。错误抛出用于调试目的,而不是用于验证。 (7认同)
  • @RahulMahadik因为expect(...)会在准备好检测/捕获抛出的错误时调用匿名函数。如果省略匿名箭头函数,则在代码执行时将立即调用抛出函数,从而立即退出执行。 (2认同)

Bas*_*sem 8

另一个解决方案:您也可以使用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();
}
Run Code Online (Sandbox Code Playgroud)

编辑

我找到了一种单行替代方案:

expect(screen.queryByTestId("your-test-id")).not.toBeInTheDocument();
Run Code Online (Sandbox Code Playgroud)