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

React组件hover测试失效:opacity样式验证失败求助

问题:测试按钮hover状态的opacity样式不生效

测试按钮hover状态下的opacity样式时,尝试用userEvent.hover(hoverButton)和fireEvent.mouseOver(hoverButton)两种方法均未生效,但disabled状态下的cursor:not-allowed等样式能正常验证。

相关代码

Button.js

import styled from 'styled-components';

const ButtonWrapper = styled.button`
  color: #fff;
  background-color: tomato;
  font-size: 14px; 
  padding: 6px 30px;
  height: 35px;

  &:not(:disabled):hover {
    opacity: 0.8;
    background: red;
  }

  ${({ disabled }) =>
    disabled && `
      opacity: 0.4;
      cursor: not-allowed;
    `}
`;

const Button = ({ children, className, disabled, size = 'medium' }) => {
  return <ButtonWrapper
    className={className}
    disabled={disabled}
    onClick={() => console.log('Hello mate')}
    size={size}
  >{children}</ButtonWrapper>;
}

export default Button;

Button.test.js

import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from "@testing-library/user-event";
import Button from './index';

test('should render button', () => {
  render(<Button>Click on me</Button>);
  expect(screen.getByText(/Click on me/i)).toBeInTheDocument();
});

test('should render disabled button', () => {
  render(<Button disabled>hover on me</Button>);
  const hoverButton = screen.getByRole('button');
  
  expect(hoverButton).toBeDisabled();
  expect(hoverButton).toHaveStyle('opacity: 0.4')
  expect(hoverButton).toHaveStyle('cursor:not-allowed')
});

test('should hover button', () => {
  render(<Button>hover on me</Button>);
  const hoverButton = screen.getByRole('button', { name: 'hover on me' });
  
  userEvent.hover(hoverButton);
  // fireEvent.mouseOver(hoverButton)

  expect(hoverButton).toHaveStyle('opacity: 0.8')
  expect(hoverButton).toHaveStyle(`background-color: #000`);
});

test('toMatchSnapshot', () => {
  const { asFragment } = render(<Button>Click on me</Button>);
  expect(asFragment()).toMatchSnapshot();
});

解决办法

1. 修正断言错误

测试代码中,hover状态的背景色实际为red,但断言写的是background-color: #000,这会直接导致断言失败,先修正这个错误:

expect(hoverButton).toHaveStyle(`background-color: red`);

2. 解决伪类样式检测问题

React Testing Library默认使用的JSDOM环境不会自动应用:hover这类伪类样式,直接用toHaveStyle无法检测到。推荐使用jest-styled-components扩展Jest匹配器,它能正确识别styled-components生成的伪类样式:

  • 安装依赖:
npm install --save-dev jest-styled-components
  • 在测试文件顶部引入:
import 'jest-styled-components';
  • 修改hover测试的断言逻辑,使用toHaveStyleRule匹配器:
test('should hover button', async () => {
  render(<Button>hover on me</Button>);
  const hoverButton = screen.getByRole('button', { name: 'hover on me' });
  
  await userEvent.hover(hoverButton);

  expect(hoverButton).toHaveStyleRule('opacity', '0.8', {
    modifier: ':not(:disabled):hover'
  });
  expect(hoverButton).toHaveStyleRule('background', 'red', {
    modifier: ':not(:disabled):hover'
  });
});

这样就能正确检测到hover状态下的样式了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:01:06