如何用React Testing Library和Jest测试元素display: none样式?
React Testing Library + Jest 断言CSS hover样式失败的解决办法
问题背景
我刚用React Testing Library和Jest写React单元测试,想验证CSS属性是否生效:元素初始display: none,鼠标悬停所在卡片后,元素display: block且color: hsl(0, 0%, 93%)。但用toHaveStyle断言一直失败,测试代码如下:
test('Card like-function is working correctly', async() => { const user = userEvent.setup(); render(<Card card={cardData}/>); const card = screen.getByRole('article', {name: 'card'}); const like = screen.getByText('❤'); expect(like).toHaveStyle('display: none'); await user.hover(card); const likeHover = screen.getByText('❤'); expect(like).toHaveStyle('display: block'); expect(likeHover).toHaveStyle('color: hsl(0, 0%, 93%)'); })
解决思路和修改方案
1. toHaveStyle的局限性:只检查内联样式
toHaveStyle默认只会读取元素的内联style属性,如果你的样式是通过外部CSS、CSS Modules或者非内联的CSS-in-JS定义的,这个方法就拿不到生效的样式。这时候应该用getComputedStyle获取浏览器计算后的实际样式。
2. 处理hover后的异步样式更新
hover触发的样式变化可能配合React状态异步更新,需要用waitFor包裹断言,确保样式更新完成后再检查。
3. 注意颜色值的解析格式
浏览器会把hsl(0, 0%, 93%)解析成对应的RGB值(rgb(237, 237, 237)),直接断言hsl值会失败,需要用解析后的RGB值。
修改后的测试代码
import { waitFor } from '@testing-library/react'; test('Card like-function is working correctly', async () => { const user = userEvent.setup(); render(<Card card={cardData} />); const card = screen.getByRole('article', { name: 'card' }); const like = screen.getByText('❤'); // 初始状态:检查计算后的display样式 expect(getComputedStyle(like).display).toBe('none'); // 触发hover await user.hover(card); // 等待样式更新并断言 await waitFor(() => { expect(getComputedStyle(like).display).toBe('block'); // 用浏览器解析后的RGB值断言颜色 expect(getComputedStyle(like).color).toBe('rgb(237, 237, 237)'); }); });
额外说明
如果你的样式确实是内联样式,也可以用toHaveStyle的对象形式来避免字符串匹配的空格问题:
expect(like).toHaveStyle({ display: 'none' });
内容的提问来源于stack exchange,提问作者Erandro
相关产品推荐
相关产品推荐

