You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:12:21