jestjs - 未调用 React-testing-library 模拟函数
问题描述
我正在尝试测试我的组件:
在我的组件中,当我单击按钮时,我调用了一些函数并传递了一些 id。
我的测试:
it("should call function on submit click", async () => {
const wrapper = render(<Component />);
const id = "1";
const handleSubmit = jest.fn();
const SubmitBtn = wrapper.getByTestId("submit-btn");
fireEvent.click(SubmitBtn);
await waitFor(() => wrapper);
expect(handleSubmit).toHaveBeenCalled();
});
在这里我试过:
expect(handleSubmit).toHaveBeenCalled();
expect(handleSubmit).toHaveBeenCalledWith(id);
expect(handleSubmit).toBeCalled();
expect(handleSubmit).toBeCalledWith(id)
尝试了一切,但它不起作用..
expect(jest.fn()).toBeCalled()
Expected number of calls: >= 1
Received number of calls: 0
解决方案
你的模拟不能被称为这个,因为你在渲染你的组件之后声明了它。我假设您的组件中有一个 handleSubmit 函数,该函数在提交单击时被调用,但是当您调用时:
const handleSubmit = jest.fn();
...该组件已经是渲染器,您无法模拟它的 handleSubmit 函数。
我的建议:
不要试图窥探 handleSubmit 函数,像真实用户一样测试
您不应该尝试测试内部组件逻辑,而是测试真实用户会看到的内容:加载微调器、确认消息……这就是促进 RTL 的原因,因为它会让您对测试充满信心,将您的测试与内部分离实现(这对于 React 组件单元测试来说是一件好事),并迫使您作为开发人员在编写代码时首先考虑用户(考虑如何使用 RTL 测试代码会迫使您考虑用户体验)。
在您的测试中,您可以这样做:
// in component
const handleSubmit = () => {
// do things
// say that this boolean controls a message display
setSubmittedMessageDisplay(true);
}
测试中
it('should call function on submit click', async () => {
const wrapper = render(<Component />);
const submitBtn = wrapper.getByTestId('submit-btn');
fireEvent.click(submitBtn);
expect(wrapper.getByText('form submitted - controlled by submittedMessageDisplay')).toBeTruthy();
});
从父组件向下传递表单提交处理程序,模拟它
这意味着将事情提升到父组件:
// in parent
const handleSubmit = () => {...}
<ChildWithForm onSubmit={handleSubmit} />
// in child
<Form onSubmit={props.onSubmit}>...</Form>
然后在你的测试中你可以这样做:
test('submits form correctly', () => {
const mockedHandler = jest.fn();
const wrapper = render(<Child onSubmit={mockedHandler} />);
const submitBtn = wrapper.getByTestId('submit-btn');
fireEvent.click(submitBtn);
expect(mockedHandler).toHaveBeenCalled();
});
推荐阅读
- powerbi - PowerBI:显示所有轴值,与所选内容无关
- java - 用于 Java 的 IntSet 的 toString
- java - 从 gradle api 插件中检索依赖 jar 文件
- python - 如何将一个表中的几列的行插入另一个表并传递其他几列的默认值?
- c - Linux 设备驱动程序在链接时的参数
- mysql - 从 MySQL 中的逗号分隔字段中删除重复项和计数
- react-native - 如何在 React Native 中实现渲染音轨?
- android - 无法在家庭 WLAN 中通过 wifi 连接 ADB
- javascript - 分离网络图节点之间的多个链接
- python - css的find_element没有按预期工作