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

使用jest-dom与styled-components测试按钮hover样式时异常:hover测试匹配到active样式

使用jest-dom与styled-components测试按钮hover样式时异常:hover测试匹配到active样式

我之前碰到过类似的问题,结合你的代码和错误信息来看,大概率是这几个原因导致的:

问题根源分析

  1. CSS伪类顺序引发的样式覆盖
    你在Button.styles.ts里把:active伪类写在了:hover之后,这两个伪类的CSS优先级完全相同,所以当元素同时触发:hover和:active状态时,:active的样式会直接覆盖:hover的。测试环境里的模拟行为和真实浏览器有差异,导致hover测试时按钮意外触发了active状态,从而读取到了错误的样式。

  2. 测试用例的小错误
    你的点击测试用例里,期望的transform样式是scale(0.95),但实际:active定义的是translateY(0.3rem),这个错误本身就会导致点击测试失败,虽然不是hover问题的直接原因,但也需要修正。

  3. 测试工具的状态模拟差异
    @testing-library/user-event的hover方法在JSDom环境下的模拟可能和真实浏览器有差异,没有正确隔离hover和active的状态。

解决方案

方案一:修正测试用例,改用更直接的事件模拟

先把点击测试的期望样式修正正确,然后给hover测试改用fireEvent来模拟鼠标事件,它的行为更贴近真实DOM事件,能减少状态混淆:

// 记得导入fireEvent
import { screen, render, fireEvent } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import Button from "./Button";
import Theme from "../../Theme";

describe("Button", () => {
  it("should render with correct children", () => {
    render(
      <Theme>
        <Button>Entrar</Button>
      </Theme>
    );

    const button = screen.getByText(/entrar/i);
    expect(button).toBeInTheDocument();
  });

  it("should not render any children if isLoading is passed as true", () => {
    render(
      <Theme>
        <Button isLoading={true}>Entrar</Button>
      </Theme>
    );

    const button = screen.queryByText(/entrar/i);
    expect(button).not.toBeInTheDocument();
  });

  it("should apply proper style when user hovers over it", () => {
    render(
      <Theme>
        <Button>Entrar</Button>
      </Theme>
    );

    const button = screen.getByText(/entrar/i);
    // 用mouseEnter模拟hover状态
    fireEvent.mouseEnter(button);
    expect(button).toHaveStyle({
      backgroundColor: "#000000",
      transform: "scale(1.05)"
    });
    // 测试完成后模拟鼠标离开,避免影响后续测试
    fireEvent.mouseLeave(button);
  });

  it("should apply proper style when user clicks it", () => {
    render(
      <Theme>
        <Button>Entrar</Button>
      </Theme>
    );

    const button = screen.getByText(/entrar/i);
    userEvent.click(button);
    // 修正为:active实际定义的样式
    expect(button).toHaveStyle("transform: translateY(0.3rem)");
  });
});

方案二:确保测试用例的独立性

把所有测试用例都放在describe块内部,这样jest会更稳定地按顺序执行,减少跨测试的状态残留风险(虽然testing-library默认会自动清理,但规范的结构能避免很多意外)。

方案三:检查依赖兼容性

如果上面的方法都不行,可以尝试更新jest-environment-jsdom、@testing-library/react和styled-components到最新的兼容版本,有时候旧版本的工具链会存在伪类模拟的bug。

备注:内容来源于stack exchange,提问作者joaovitorfelix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 13:50:28