使用 react-testing-library 时如何测试组件是否使用正确的 props 渲染?
How to test if a component is rendered with the right props when using 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>
)
问题是我不喜欢为已经在其他地方测试过的功能在每个组件上添加测试,所以我认为这应该足以测试组件是否已呈现并且我正在向它传递正确的道具。
我本来可以用 Enzyme 像这样轻松地测试它:
expect(wrapper.find('FetchNextPageButton').props()).toMatchObject({
query: NEWS_QUERY,
path: "viewer.news"
})
所以我想知道使用 React testing library 来测试它的最佳方法是什么。
不相信这是可能的。 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
这是 Kent C. Dodds(RTL 的创始人)与他讨论后分享给我的方法:
import FetchNextPageButton from 'FetchNextPageButton'
jest.mock('FetchNextPageButton', () => {
return jest.fn(() => null)
})
// ... in your test
expect(FetchNextPageButton).toHaveBeenCalledWith(props, context)
就我而言,我想测试高阶组件 (HOC) 是否正确地增强了传递给 HOC 的组件。
我需要做的是使实际组件成为模拟并将其传递给 HOC。就像现有答案中描述的那样,您可以期待 HOC 添加的属性。
// after 'Component' get's passed into withSelectionConstraint, it should have an id prop
const Component = jest.fn(() => <h1>Tag Zam</h1>);
const WithConstraint = withSelectionConstraint(Component, ["instance"], true);
render(<WithConstraint />);
// passing the jest mock to the HOC, enables asserting the actual properties passed by the HOC
expect(Component).toHaveBeenCalledWith(
expect.objectContaining({ ids: mockInstanceRows.map(x => x.id) }),
expect.anything()
)
我有一些组件正在渲染另一个已经单独测试过的组件 (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>
)
问题是我不喜欢为已经在其他地方测试过的功能在每个组件上添加测试,所以我认为这应该足以测试组件是否已呈现并且我正在向它传递正确的道具。
我本来可以用 Enzyme 像这样轻松地测试它:
expect(wrapper.find('FetchNextPageButton').props()).toMatchObject({
query: NEWS_QUERY,
path: "viewer.news"
})
所以我想知道使用 React testing library 来测试它的最佳方法是什么。
不相信这是可能的。 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
这是 Kent C. Dodds(RTL 的创始人)与他讨论后分享给我的方法:
import FetchNextPageButton from 'FetchNextPageButton'
jest.mock('FetchNextPageButton', () => {
return jest.fn(() => null)
})
// ... in your test
expect(FetchNextPageButton).toHaveBeenCalledWith(props, context)
就我而言,我想测试高阶组件 (HOC) 是否正确地增强了传递给 HOC 的组件。
我需要做的是使实际组件成为模拟并将其传递给 HOC。就像现有答案中描述的那样,您可以期待 HOC 添加的属性。
// after 'Component' get's passed into withSelectionConstraint, it should have an id prop
const Component = jest.fn(() => <h1>Tag Zam</h1>);
const WithConstraint = withSelectionConstraint(Component, ["instance"], true);
render(<WithConstraint />);
// passing the jest mock to the HOC, enables asserting the actual properties passed by the HOC
expect(Component).toHaveBeenCalledWith(
expect.objectContaining({ ids: mockInstanceRows.map(x => x.id) }),
expect.anything()
)