Jest中jss-snapshot-serializer无法捕获JSS嵌套选择器与@media查询变更
问题根因
默认配置下jss-snapshot-serializer仅会序列化JSS样式的顶级属性,不会递归解析媒体查询、嵌套选择器、伪类等规则,因此修改这类属性时快照比对无法识别变更。
解决配置步骤
- 第一步:升级
jss-snapshot-serializer到最新稳定版,旧版本不支持嵌套规则的序列化配置 - 第二步:在Jest初始化文件(通常为
setupTests.js/jest.setup.js)中自定义序列化器配置,开启嵌套规则和媒体查询的捕获:
import jssSnapshotSerializer from 'jss-snapshot-serializer'; import { create } from 'jss'; import preset from 'jss-preset-default'; // 初始化和项目中一致的JSS实例 const jss = create(preset()); expect.addSnapshotSerializer(jssSnapshotSerializer({ jss, // 开启媒体查询规则序列化 includeMediaQueries: true, // 开启嵌套选择器(包含&生成的子类、伪类、伪元素等)序列化 includeNestedSelectors: true, // 可选:关闭classname哈希混淆,提升快照可读性 classNameFormat: 'plain' }));
- 第三步:测试用例中统一使用同一个JSS实例渲染组件,避免序列化器无法匹配到样式规则,以react-jss为例:
import { JssProvider } from 'react-jss'; import { render } from '@testing-library/react'; import MyComponent from './MyComponent'; // 导入和序列化器配置中完全相同的JSS实例 import jss from './jss-config'; test('组件样式符合预期', () => { const { container } = render( <JssProvider jss={jss}> <MyComponent /> </JssProvider> ); expect(container.firstChild).toMatchSnapshot(); });
- 第四步:删除历史快照文件,执行
jest --updateSnapshot生成新快照,新快照会包含媒体查询、嵌套选择器的全部样式,后续修改这类属性时会正常触发快照比对失败。
注意事项
如果Jest配置中同时引入了其他样式相关的快照序列化器(比如styled-components的序列化器),需要确保jss-snapshot-serializer是最后一个添加的,避免优先级冲突导致规则不生效。
内容的提问来源于stack exchange,提问作者Daniel Toro
相关产品推荐
相关产品推荐

