测试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
相关产品推荐
相关产品推荐

