如何为React函数式组件编写mouseover与mouseleave的Jest测试用例
解决函数式组件mouseover/mouseleave事件的Jest+Enzyme测试问题
问题根源
你遇到的ShallowWrapper::state() can only be called on class component错误,是因为函数式组件通过useState创建的状态属于组件内部闭包变量,Enzyme的wrapper.state()方法仅支持类组件的state访问,无法直接获取函数组件的状态值。
正确的测试思路应该是基于组件的UI渲染结果断言,而非直接访问内部状态——测试要验证的是组件行为是否符合预期,而非内部状态的具体值。
修正后的测试用例
完整测试代码如下:
import React from "react"; import { shallow } from "enzyme"; import Toggle from "./Toggle"; import { SearchMenu } from "./Toggle"; describe("Toggle Component", () => { it("shows/hides SearchMenu on mouseover/mouseleave", () => { const wrapper = shallow(<Toggle />); const searchTypeDiv = wrapper.find(".search-type"); // 初始状态:dropdownShown为false,SearchMenu不渲染 expect(wrapper.find(SearchMenu).exists()).toBe(false); // 模拟mouseover事件,验证SearchMenu渲染 searchTypeDiv.simulate("mouseover"); expect(wrapper.find(SearchMenu).exists()).toBe(true); // 模拟mouseleave事件,验证SearchMenu隐藏 searchTypeDiv.simulate("mouseleave"); expect(wrapper.find(SearchMenu).exists()).toBe(false); }); });
关键修改点
- 移除所有
wrapper.state()相关代码,改为断言SearchMenu组件的存在性 - 修正
wrapper.find(<SearchMenu />)为wrapper.find(SearchMenu)(Enzyme查找组件需传入组件引用而非JSX元素) - 调用
exists()方法而非直接引用exists属性(exists是方法,需要执行) - 明确获取绑定事件的
.search-type元素,模拟事件更精准
补充说明
如果需要更细致的测试(比如验证事件触发时状态更新逻辑),也可以通过jest.spyOn监听setDropdownShown,但对于UI交互测试来说,断言渲染结果已经足够覆盖核心逻辑,且更符合测试的"黑盒"原则——不需要关心组件内部如何实现,只需要验证输入(事件)和输出(UI变化)是否匹配。
内容的提问来源于stack exchange,提问作者Sandhya
相关产品推荐
相关产品推荐

