Angular 14单元测试浅层渲染快照因__ngContext__值不一致失败
Angular 14 + Jest 28 快照测试__ngContext__属性差异问题解决方法
问题背景
在使用Angular 14搭配Jest 28和ng-mocks进行单元测试时,单独运行与批量运行测试生成的快照中,<mock-render>标签的__ngContext__属性值不一致(分别为__ngContext__="0"和__ngContext__={[Function Number]}),导致快照测试失败。
解决方法
方法1:自定义Jest快照序列化器过滤__ngContext__属性
创建自定义序列化器,在生成快照时自动移除__ngContext__属性:
- 在项目中创建
src/jest.serializer.ts文件:
import type { JasmineSerializer } from 'jest-preset-angular/build/serializers/jasmine-serializer'; const angularSerializer = require('jest-preset-angular/build/serializers/jasmine-serializer').default as JasmineSerializer; export default { test(val: any): boolean { return angularSerializer.test(val); }, print(val: any, serialize: (val: any) => string): string { let result = angularSerializer.print(val, serialize); // 移除两种格式的__ngContext__属性 result = result.replace(/__ngContext__="[^"]*"\s*/g, ''); result = result.replace(/__ngContext__=\{[^\}]*\}\s*/g, ''); return result; }, };
- 在
jest.config.ts中配置该序列化器:
export default { // 其他原有配置... snapshotSerializers: [ '<rootDir>/src/jest.serializer.ts', 'jest-preset-angular/build/serializers/no-ng-attributes', 'jest-preset-angular/build/serializers/ng-snapshot', 'jest-preset-angular/build/serializers/html-comment', ], };
方法2:调整快照断言目标,直接渲染组件元素
不要断言整个fixture,改为获取组件的原生元素进行快照,避开<mock-render>标签的额外属性:
修改测试代码:
import { MockBuilder, MockRender } from 'ng-mocks'; describe('Snapshot Tests', () => { beforeEach(() => MockBuilder(MyComponent, [ MyModule ]) ); it('should create', () => { const fixture = MockRender(MyComponent, {}); // 断言组件的原生元素而非整个fixture expect(fixture.debugElement.nativeElement).toMatchSnapshot(); }); });
方法3:通过ng-mocks配置忽略特定属性
利用ng-mocks的配置项,直接指定忽略__ngContext__属性:
import { MockBuilder, MockRender } from 'ng-mocks'; describe('Snapshot Tests', () => { beforeEach(() => MockBuilder(MyComponent, MyModule) // 配置忽略指定属性 .configure({ render: { ignoreAttributes: ['__ngContext__'], }, }) ); it('should create', () => { const fixture = MockRender(MyComponent, {}); expect(fixture).toMatchSnapshot(); }); });
也可以直接在MockRender时传入配置:
const fixture = MockRender(MyComponent, {}, { render: { ignoreAttributes: ['__ngContext__'], }, });
验证方案
修改完成后,重新生成快照:
npx jest --updateSnapshot
之后无论单独运行还是批量运行测试,快照都会保持一致,不会再出现__ngContext__属性的差异。
内容的提问来源于stack exchange,提问作者N33D
相关产品推荐
相关产品推荐

