使用Vitest测试React组件遇两类错误:Spy未调用与TS属性报错
解决Vitest测试React Login组件的两个问题
问题1:点击按钮后Spy未被调用(expected "spy" to be called once, but got 0 times)
常见原因及修复方案:
- 事件绑定错误:如果Login组件是表单结构,要确认是监听表单的
onSubmit事件而非按钮的onClick,同时按钮要设置type="submit",否则点击按钮不会触发提交逻辑。 - 事件触发方式不对:测试时优先触发表单的
submit事件(比如fireEvent.submit(formElement)),而非直接点击按钮——部分场景下按钮点击会因表单验证等逻辑拦截,导致submitHandler不执行。 - 异步操作未等待:若
submitHandler是异步函数,测试里要加await等待事件完成,比如await userEvent.click(button)。 - Spy未正确传入:确保测试中创建的mock函数确实传到了组件的对应props上(和问题2的TS错误直接相关,props定义错误会导致传参无效)。
问题2:传递submitHandler时的TypeScript错误(Type '{ submitHandler: Mock<any, any>; }' is not assignable to type 'IntrinsicAttributes')
本质是Login组件未定义submitHandler这个props的类型,TS无法识别该属性的合法性,修复步骤:
- 给Login组件添加Props类型定义:
// Login.tsx type LoginProps = { submitHandler: (formData: { username: string; password: string }) => void; }; export const Login = ({ submitHandler }: LoginProps) => { // 组件逻辑代码 };
- 若组件用默认导出,也要确保类型关联正确,这样TS就能识别
submitHandler是合法props,错误会自动消失。
修正后的测试代码示例
假设Login组件是表单结构,测试代码可参考:
import { render, screen, fireEvent } from '@testing-library/react'; import { vi } from 'vitest'; import { Login } from './Login'; test('表单提交时触发submitHandler', () => { const submitHandler = vi.fn(); render(<Login submitHandler={submitHandler} />); // 填写表单输入框 fireEvent.change(screen.getByLabelText(/用户名/i), { target: { value: 'test_user' } }); fireEvent.change(screen.getByLabelText(/密码/i), { target: { value: '123456' } }); // 触发表单提交 fireEvent.submit(screen.getByRole('form')); // 验证spy被调用 expect(submitHandler).toHaveBeenCalledTimes(1); });
内容的提问来源于stack exchange,提问作者user2024080
相关产品推荐
相关产品推荐

