使用React测试库检查文本是否出现在元素中

78

我正在使用Testing Library为一个React应用编写一些测试。我想要检查是否出现了某些文本内容,但我需要确认它出现在特定的位置,因为我已经知道它出现在其他地方。

Testing Library查询文档中指出getByText查询接收一个container参数,我猜想这个参数可以让你在该容器内搜索。我按照文档中指定的顺序尝试了一下,并使用containertext参数:

const container = getByTestId('my-test-id');
expect(getByText(container, 'some text')).toBeTruthy();

我得到一个错误:matcher.test不是一个函数

如果我反过来放置参数:

const container = getByTestId('my-test-id');
expect(getByText('some text', container)).toBeTruthy();

我遇到了一个不同的错误:找到多个文本为“some text”的元素

这意味着它没有在指定的容器内进行搜索。

我想我没有理解getByText的工作原理。我做错了什么?


你可以使用 expect(container.textContent).toMatch('some text') 获取文本。 - taystack
3个回答

87

最好使用within 来处理这种情况:

render(<MyComponent />)
const { getByText } = within(screen.getByTestId('my-test-id'))
expect(getByText('some text')).toBeInTheDocument()

如果使用 getByText 找不到文本,会抛出错误。那么使用 expect....toBeInTheDocument 的意义是什么?以下是解决方案。 - jacobcan118
9
这不应该被接受作为答案,因为根据文档:“避免从render结果中解构查询,而是使用screen.getByTestId”。 - Carmine Tambascia
1
避免从查询函数解构,而是将整个函数传递给组件并让它们处理剩下的部分。详情请见:https://develop.sentry.dev/frontend/using-rtl/#:~:text=Avoid%20destructuring%20query%20functions%20from,take%20care%20of%20the%20rest. - Carmine Tambascia
1
@carmine-tambascia 谢谢。看起来这只是为了开发者而提供的小贴士,没有更多的内容。 - ddblair
@carmine-tambascia 另外,那些不是React Testing Library文档。文档可以在这里找到:[https://testing-library.com/docs/react-testing-library/intro/]。 - ddblair
显示剩余4条评论

75

另一种方法来做到这一点

import {render, screen} from '@testing-library/react';

...

  render(<MyComponent />);
  expect(screen.getByTestId('my-test-id')).toHaveTextContent('some text');

请注意,现在建议使用screen替代render的结果。

(StackOverflow帖子指向KC Dobbs的文章解释原因:react-testing-library - Screen vs Render queries


5
在这里所描述的链接中,为了使用toHaveTextContent匹配器,您可能需要添加import "@testing-library/jest-dom/extend-expect";。请注意,翻译已经尽力使句子易懂,但未更改原始含义。 - ggorlen
推荐使用screen... 但为什么?不妨提供一个由那些做出推荐的人分享的链接。 - lmat - Reinstate Monica
1
这是另一个关于屏幕(screen)与渲染(render)的SO帖子,指向了KC Dobbs的解释: https://dev59.com/9lIH5IYBdhLWcg3wDIQe - Seth McClaine
很不幸,在 toHaveTextContent 上我得到了“类型 'HTMLElement' 上不存在属性 'toHaveTextContent'”。 - Carmine Tambascia
2
这很简单,对我来说完美地运作了 :) 谢谢 - Kevin Oswaldo
2
似乎这比被接受的答案更好,后者需要强制使用特定的编码风格。 - kevr

7

通过这种方式,您可以更加精确地聚焦于特定的项目:

expect(queryByTestId("helperText")?.textContent).toContain("Help me!");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接