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

使用React Testing Library与Jest测试hover时无法获取预期样式如何解决

核心原因

  • 第一,userEvent.hover 是异步方法,你当前的代码没有加 await,事件还没完成触发就执行了后续断言逻辑。
  • 第二,也是最关键的:jsdom(RTL底层依赖的DOM模拟环境)不支持CSS伪类样式的自动匹配。你就算正确触发了mouseenter/mouseover事件,jsdom也不会让元素进入:hover匹配状态,写在CSS :hover选择器下的样式自然不会生效,你拿到的永远是默认样式。
  • 第三,你设置了0.2s的过渡效果,就算样式能生效,默认的断言时机也早于过渡完成的时间,拿不到最终样式。

解决方案

根据你的场景可以选任意一种:

方案1:修改业务实现方式,适配单元测试

把hover状态从CSS伪类改为JS控制的类名:

  1. 组件内监听mouseenter和mouseleave事件,动态给按钮添加/移除is-hover类
  2. 把原来写在&:hover下的样式挪到&.is-hover下
  3. 修正测试代码,添加await,调整等待逻辑:
it("should expect the button to shift box-shadow on hover", async () => {
  render(<PrimaryButton aria-label="sign up">Sign Up</PrimaryButton>);
  const button = screen.getByRole("button", { name: /sign up/i });
  // 必须加await等待hover事件触发完成
  await userEvent.hover(button);
  // 等待过渡完成,timeout设为大于过渡时长即可
  await waitFor(() => {
    expect(button).toHaveStyle(
      "box-shadow: rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px;"
    );
  }, { timeout: 300 });
});

如果不想等待过渡时间,可以在测试全局样式里添加规则禁用过渡,执行效率更高:

* {
  transition: none !important;
  animation: none !important;
}

方案2:改用端到端测试工具

如果不想修改业务代码,可以用Cypress、Playwright这类在真实浏览器环境运行的测试工具,浏览器原生支持:hover伪类的状态匹配,无需修改业务逻辑即可正常测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:57:00