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

Emi*_*Emi 22 javascript reactjs jestjs react-testing-library

我有一些组件正在呈现已经单独测试的另一个组件(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>
)
Run Code Online (Sandbox Code Playgroud)

问题是我不想为已经在其他地方测试过的功能在这些组件中的每一个上添加测试,所以我认为这应该足以测试组件是否已呈现并且我正在通过正确的道具。

我本来可以使用 Enzyme 轻松地进行测试,如下所示:

expect(wrapper.find('FetchNextPageButton').props()).toMatchObject({
  query: NEWS_QUERY,
  path: "viewer.news"
})
Run Code Online (Sandbox Code Playgroud)

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

Emi*_*Emi 32

This is the approach that Kent C. Dodds (the creator of RTL) shared with me after discussing it with him:

import FetchNextPageButton from 'FetchNextPageButton'

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

// ... in your test
expect(FetchNextPageButton).toHaveBeenCalledWith(props, context)
Run Code Online (Sandbox Code Playgroud)

  • 我是唯一一个这不起作用的人吗?当我运行时,它指出:匹配器错误:接收到的值必须是模拟或间谍函数接收到的类型:函数接收到的值:[函数组件] (3认同)
  • @AlexMckay,我们在此 Twitter 帖子中讨论了它:https://twitter.com/kentcdodds/status/1189662486007468032 (2认同)
  • 注意:Kent C. Dodds 不推荐这种方法。他编写了展示如何执行此操作的代码片段,但表示他不推荐该方法(这也在 Twitter 线程中)。类似的问题[此处](/sf/answers/4545793381/) (2认同)

sky*_*yer 5

不要相信这是可能的。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");
Run Code Online (Sandbox Code Playgroud)

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

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

PStoHaveAttribute来自jest-dom