使用 react-testing-library 时如何测试组件是不是使用正确的道具呈现?

Posted

技术标签:

【中文标题】使用 react-testing-library 时如何测试组件是不是使用正确的道具呈现?【英文标题】:How to test if a component is rendered with the right props when using react-testing-library?使用 react-testing-library 时如何测试组件是否使用正确的道具呈现? 【发布时间】:2020-02-25 15:38:24 【问题描述】:

我有一些组件正在渲染另一个已经单独测试过的组件 (FetchNextPageButton),例如:

const News = () => (
  <div>
    <h1>News</h1>
    ...
    <FetchNextPageButton query=NEWS_QUERY path="viewer.news" />
  </div>
)

const Jobs = () => (
  <div>
    <h1>Jobs</h1>
    ...
    <FetchNextPageButton query=JOBS_QUERY path="viewer.jobs" />
  </div>
)

const Posts = () => (
  <div>
    <h1>Posts</h1>
    ...
    <FetchNextPageButton query=POSTS_QUERY path="viewer.posts" />
  </div>
)

问题是我不希望为已经在其他地方测试过的功能在每个组件上添加测试,所以我认为这足以测试组件是否已呈现并且我' m 将正确的道具传递给它。

我可以使用 Enzyme 轻松测试这一点,如下所示:

expect(wrapper.find('FetchNextPageButton').props()).toMatchObject(
  query: NEWS_QUERY,
  path: "viewer.news"
)

所以我想知道使用React testing library 来测试它的最佳方法是什么。

【问题讨论】:

【参考方案1】:

这是 Kent C. Dodds(RTL 的创建者)与他讨论后与我分享的方法:

import FetchNextPageButton from 'FetchNextPageButton'

jest.mock('FetchNextPageButton', () => 
  return jest.fn(() => null)
)

// ... in your test
expect(FetchNextPageButton).toHaveBeenCalledWith(props, context)

【讨论】:

@AlexMckay 我们在这个推特线程中讨论过它:twitter.com/kentcdodds/status/1189662486007468032 我是唯一不适合的人吗?当我运行它时状态:匹配器错误:接收到的值必须是模拟或间谍函数接收到的类型:函数接收到的值:[函数组件] @Youans 你必须先模拟组件,然后将其传递给断言。 注意:Kent C. Dodds 不推荐这种方法。他编写了代码 sn-p 来展示如何做到这一点,但表示他不推荐这种方法(这也在 twitter 线程中)。类似问题here @Doug 我知道他不建议根据经验这样做,但如果你必须这样做(他说,可能有充分的理由单独测试),他实际上就是这样做的。【参考方案2】:

不要相信这是可能的。 RTL 看起来专注于验证 DOM 而不是 React 的组件树。

我看到的唯一解决方法是模拟 FetchNextPageButton 以使其将所有道具渲染为属性。

jest.mock("../../../FetchNextPageButton.js", () => 
  (props) => <div data-test-id="FetchNextPageButton" ...props />);
....
const  getByTestId  = render(<YourComponent />);
expect(getByTestId("FetchNextPageButton")).toHaveAttribute("query", NEWS_QUERY);
expect(getByTestId("FetchNextPageButton")).toHaveAttribute("path", "viewer.news");

当然,这仅适用于 props 中的原始值,但验证对象或函数之类的东西会更难。

想想,这不是 RTL 方式,但我同意在每个容器的范围内检查它会是一项巨大的工作(并且完全忽略这将是相当冒险的)。

PS toHaveAttribute 来自jest-dom

【讨论】:

这将要求所有的道具都是小写的,这有点限制,因为渲染或动作函数会抛出无法识别道具的警告。 @KhalifaGad 是的,这是真的。如果您不喜欢看到警告,您总是可以编写更复杂的模拟。

以上是关于使用 react-testing-library 时如何测试组件是不是使用正确的道具呈现?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React-Testing-Library 测试 mapDispatchToProps?

如何使用 Jest 和 react-testing-library 测试 useRef?

react-testing-library - 屏幕与渲染查询

如何使用 react-testing-library 测试由其他组件组成的组件?

使用 react-testing-library 时如何测试组件是不是使用正确的道具呈现?

使用 react-testing-library 时找不到带有文本的元素:“myText”错误