如何使用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
相关产品推荐
相关产品推荐

