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

测试React组件时userEvent.hover()为何不触发mouseEnter事件?

Tippy.js提示框测试:userEvent.hover()为何无法触发mouseEnter事件?

我在项目中使用Tippy.js实现提示框,官方文档说明提示框由mouseEnter或focus事件触发。测试时发现:

  • 使用fireEvent.mouseEnter()可以成功触发提示框,测试通过
  • 使用userEvent.hover()和fireEvent.mouseOver()都无法触发提示框

想搞清楚userEvent.hover()是不是不支持mouseEnter事件,以及失效的具体原因。


问题原因解析

userEvent.hover()的行为更贴近原生鼠标悬停的真实流程,它会依次触发**mouseOver、mouseMove、mouseOut(若目标元素存在父元素)等事件,但不会触发mouseEnter事件**——而Tippy.js恰好是监听mouseEnter来触发提示框显示的,这就是两者不兼容的核心原因。

对比fireEvent.mouseEnter(),它是直接模拟触发了mouseEnter事件,正好命中Tippy.js的监听逻辑,所以能成功触发提示框。

额外补充:fireEvent.mouseOver()无效也是因为Tippy.js没有监听该事件,仅监听了mouseEnter。


可复现代码

组件代码

import React from "react";
import Tippy from "@tippyjs/react";

const App = () => (
  <Tippy content={<span>Tooltip</span>}>
    <button>My button</button>
  </Tippy>
);

export default App;

测试代码

import React from "react";
import { fireEvent, render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import user from "@testing-library/user-event";
import App from "./App";

// 失败的测试:user.hover()无法触发提示框
test("userEvent.hover() 无法触发Tippy提示框", async () => {
  render(<App />);

  const button = screen.getByRole("button", { name: /my button/i });

  user.hover(button);
  // 此处会找不到Tooltip文本,测试失败
  expect(await screen.findByText(/tooltip/i)).toBeInTheDocument();
});

// 成功的测试:fireEvent.mouseEnter()可以触发提示框
test("fireEvent.mouseEnter() 可以触发Tippy提示框", () => {
  render(<App />);

  const button = screen.getByRole("button", { name: /my button/i });

  fireEvent.mouseEnter(button);
  expect(screen.getByText(/tooltip/i)).toBeInTheDocument();
});

内容的提问来源于stack exchange,提问作者Subrato Pattanaik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:15:55