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

IT技术 javascript reactjs jestjs react-testing-library
2021-05-23 08:41:55

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

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

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

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

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

2个回答

这是 Kent C. Dodds(RTL 的创造者)在和他讨论后分享给我的方法:

import FetchNextPageButton from 'FetchNextPageButton'

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

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

不要相信这是可能的。RTL 看起来更像是针对 DOM 而非 React 的组件树进行验证。

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

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 方式,但我同意在每个容器的范围内检查它会是一项艰巨的工作(完全忽略这将是一个风险)。

PStoHaveAttribute来自jest-dom