Jest测试mockSetCourses调用次数为0,不符合预期1次如何排查?
mockSetCourses未被调用排查方案
1. 异步逻辑未等待执行
你的提交流程包含多层异步逻辑:React-Hook-Form的表单校验、sendRequest请求、请求成功后的回调执行,你在点击按钮后直接断言,此时异步逻辑尚未跑完,setCourses还未被触发。
修复方案
- 首先mock
sendRequest让其直接触发成功回调,避免等待真实接口请求:
// 替换为你实际的sendRequest模块路径 jest.mock('@/utils/request', () => ({ sendRequest: jest.fn((method, url, successCallback) => { successCallback(); // 立刻执行成功回调 }) }));
- 改造测试用例,使用
waitFor等待异步逻辑执行完成后再断言:
test("Admin page calls mockSetCourses when submit button is clicked for Editing a Course", async () => { userEvent.click(screen.getByTestId("adminSubmitButton")); await waitFor(() => { expect(mockSetCourses).toHaveBeenCalledTimes(1); }); });
2. 表单校验未通过未触发onSubmit
React-Hook-Form如果配置了字段校验规则,测试时未给必填字段赋值的话,handleSubmit不会触发你写的onSubmit函数。
修复方案
提交前先填充所有必填表单字段,示例:
test("Admin page calls mockSetCourses when submit button is clicked for Editing a Course", async () => { // 填充必填字段,替换为你实际的表单字段选择逻辑 await userEvent.type(screen.getByRole('textbox', {name: /课程描述/i}), '测试描述内容'); await userEvent.type(screen.getByRole('textbox', {name: /课程名称/i}), '测试课程'); userEvent.click(screen.getByTestId("adminSubmitButton")); await waitFor(() => { expect(mockSetCourses).toHaveBeenCalledTimes(1); }); });
3. 业务校验拦截了editCourse执行
你的onSubmit里配置了重复集合校验、描述空值校验,只要触发任意一个错误,就不会走到editCourse的调用逻辑。
排查&修复
- 打印
collectionsDuplicates和descriptionError的值,确认测试用例下两个值都不满足错误条件 - 保证你传入的
mockData和表单填充内容不会触发上述两个校验规则
4. getCourses未正确调用传入的setCourses
你的editCourse逻辑里是通过getCourses(setCourses)来触发状态更新,若getCourses内部没有在请求完成后调用传入的setCourses参数,mock函数也不会被触发。
修复方案
直接mock getCourses让其主动调用传入的setCourses:
// 替换为你实际的getCourses模块路径 jest.mock('@/api/course', () => ({ getCourses: jest.fn((setCourses) => { setCourses([{id: 615, name: '测试课程'}]); }) }));
内容的提问来源于stack exchange,提问作者lhuf
相关产品推荐
相关产品推荐

