ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

我的意思是这个问题如此受欢迎的事实说明了 API 的直观性。

k
kentcdodds

来自DOM Testing-library Docs - Appearance and Disappearance

断言元素不存在 标准的 getBy 方法在找不到元素时会抛出错误,所以如果你想断言元素不存在于 DOM 中,可以使用 queryBy API 代替: const submitButton = screen .queryByText('submit') expect(submitButton).toBeNull() // 它不存在 queryAll API 版本返回匹配节点的数组。数组的长度对于在 DOM 中添加或删除元素后的断言很有用。 const submitButtons = screen.queryAllByText('submit') expect(submitButtons).toHaveLength(2) // 期望 2 个元素 not.toBeInTheDocument jest-dom 实用程序库提供了 .toBeInTheDocument() 匹配器,可用于断言元素是否在文档的正文中。这可能比断言查询结果为空更有意义。 import '@testing-library/jest-dom/extend-expect' // 使用 `queryBy` 来避免 `getBy` 抛出错误 const submitButton = screen.queryByText('submit') expect(submitButton).not.toBeInTheDocument( )


我的坏kentcdodds,谢谢。我使用了 getByTestId 并得到了同样的错误。而且,我没有查看常见问题解答,抱歉。很棒的图书馆!您能否修改您的答案以包含 `.toBeNull();
我相信上面的链接是指向 react-testing-library docs
新的文档站点是几天前发布的。我应该使用更永久的链接。感谢@pbre 的更新!
queryByText 用于那些想要与 getByText 等效的 null 安全的人
S
Sam

使用 queryBy / queryAllBy

如您所说,如果未找到任何内容,getBy*getAllBy* 将引发错误。

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

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

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

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


这比公认的答案要好得多。这个 API 更新了吗?
感谢您的客气话!这与 accepted answer 的功能基本相同,所以我不认为它是一个较新的 API(但我可能错了)。这个答案和接受的答案之间唯一真正的区别是,接受的答案说只有一种方法可以做到这一点(queryByTestId),而实际上有两套完整的方法,其中queryByTestId是一个具体的例子。
谢谢我更喜欢这个而不是设置测试ID
谢谢你的详细解释。这是一个如此微妙的差异,尽管在这里查看了他们的示例,但我没有看到它:github.com/testing-library/jest-dom#tobeinthedocument :face-palm:
G
Gabriel Vasile

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

expect(() => getByText('your text')).toThrow('Unable to find an element');

这很容易出错。错误抛出用于调试目的,而不是用于验证。
这在我的情况下有效,但只有在使用箭头功能之后。你能告诉我为什么我们需要它吗?没有它就行不通。
V
Valentin Garreau

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

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

expect(submitButton).not.toBeNull() // it exist

m
matrixb0ss

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

expect(() => getByTestId('time-label')).toThrow()

N
Nikola Jovanović

另一种解决方案:您也可以使用 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();
}

这会起作用,Jest 会警告您“避免有条件地调用期望”(jest/no-conditional-expect)
A
Andy Rich

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

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

这种违反了测试中没有实现细节(例如组件名称)的前提。
M
Metacoder

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

希望它是有用的。

public async checknotVisibility(page:Page,location:string) :Promise<void> 
{
    const element = await page.waitForSelector(location);
    expect(element).not.toBe(location); 
}

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅