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

如何使用RTL获取并测试侧边栏Tab样式(无需固定数值)

解决侧边栏Tab位置测试不依赖具体数值的问题

问题背景

我有一个侧边栏菜单组件,包含一个用于显示/隐藏菜单的小型Tab,Tab和菜单会根据position属性渲染在屏幕左侧或右侧。组件核心逻辑是根据position为left/right分别设置right/left的负边距值(依赖drawerBleeding常量)。

当前测试用例通过检查具体CSS值(如right: -22px)来验证位置,但这样会依赖drawerBleeding的具体数值,修改Tab尺寸时测试会失败,希望改成不依赖具体数值的验证方式。

组件相关代码片段:

const SideBar = ({ 
    position = 'left', 
    label = undefined, 
    isMenu = true,
    isOpen = true,
    width = 270,
    content,
}) => { 
// ... 组件其余代码
};

const drawerBleeding = 22;

Tab的样式逻辑:

<StyledBox
    id='tabSideBar'
    component='button'
    sx={{
        position: 'absolute',
        ...(position === 'left' && {
            right: -drawerBleeding,
            borderTopRightRadius: 16,
            borderBottomRightRadius: 16,
            boxShadow: '4px 4px 5px 0px rgba(0,0,0,0.14)',
        }),
        ...(position === 'right' && {
            left: -drawerBleeding,
            borderTopLeftRadius: 16,
            borderBottomLeftRadius: 16,
            boxShadow: '-4px 4px 5px 0px rgba(0,0,0,0.14)',
        }),
        // ... 其他样式
    }}
>
    {/* Tab内容 */}
</StyledBox>

当前测试代码:

test('renders on the left side of the screen by default', async () => {
    const getById = queryByAttribute.bind(null, 'id')
  
    const dom = render(<SideBar content={<div>Sample Content</div>} />);
    
    await waitFor(() => {
      const sideBarElement = getById(dom.container, 'tabSideBar')
      expect(sideBarElement).toHaveStyle('right: -22px');
    });
});

可行解决方案

方案1:检查样式属性的存在性(忽略具体值)

通过getComputedStyle获取元素的计算样式,验证目标属性是否被设置(而非默认的auto),同时反向验证另一侧属性为默认值,确保逻辑正确:

test('renders on the left side of the screen by default', async () => {
  const { container } = render(<SideBar content={<div>Sample Content</div>} />);
  
  await waitFor(() => {
    const sideBarElement = container.querySelector('#tabSideBar');
    const computedStyle = window.getComputedStyle(sideBarElement);
    
    // 验证right属性被设置(非默认auto)
    expect(computedStyle.right).not.toBe('auto');
    // 验证left属性保持默认auto,确保位置逻辑正确
    expect(computedStyle.left).toBe('auto');
  });
});

方案2:使用正则模糊匹配样式

利用jest-dom的toHaveStyle支持正则表达式的特性,匹配包含目标属性的样式规则,或者直接检查元素的样式文本中是否包含目标属性名:

test('renders on the left side of the screen by default', async () => {
  const { container } = render(<SideBar content={<div>Sample Content</div>} />);
  
  await waitFor(() => {
    const sideBarElement = container.querySelector('#tabSideBar');
    
    // 用正则匹配"right: 任意数值px"的样式
    expect(sideBarElement).toHaveStyle(/right: -?\d+px/);
    // 或者直接检查样式文本中包含"right"
    expect(sideBarElement.style.cssText).toContain('right');
  });
});

方案3:复用常量避免硬编码(推荐)

将drawerBleeding提取为可导出的常量,在测试中导入复用,这样修改常量值时测试会自动同步,无需手动修改测试代码:

首先在组件文件中导出常量:

export const drawerBleeding = 22;

const SideBar = ({ /* props */ }) => {
  // ... 组件代码
};

然后在测试文件中导入并使用:

import { drawerBleeding } from './SideBar';

test('renders on the left side of the screen by default', async () => {
  const { container } = render(<SideBar content={<div>Sample Content</div>} />);
  
  await waitFor(() => {
    const sideBarElement = container.querySelector('#tabSideBar');
    expect(sideBarElement).toHaveStyle(`right: -${drawerBleeding}px`);
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:13:14