Angular 16独立组件中用Jest测试Getter/Setter的问题排查
Angular 16独立组件Jest测试Getter/Setter问题排查
在Angular 16独立组件中,我用Jest测试Getter/Setter的值变化逻辑,目前除了注释中的最后一个测试用例外,其余测试均正常。该测试预期当type为type001的Record从1条变为2条时,isLastRecord变为false,但执行失败。需要解决以下问题:
- 如何修改该测试用例使其通过
- 是否需要使用Spy或其他手段
- 是否需要为其他测试用例添加Spy或模拟数据
组件TS代码
export class Component001 { isLastRecord = false; private _records: Record[]; @Input() set records(value: Record[]){ if(value) { this._records = value; this.isLastRecord = value.filter(r => r.type === 'type001').length === 1; } } get records(): Record[] { return this._records; } }
现有Jest测试代码
describe("component001", () => { let component: Component001; let fixture: ComponentFixture<Component001>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [Component001, HttpClientTestingModule] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(Component001); component = fixture.componentInstance; fixture.detectChanges(); }); describe('Component001', () => { it('Should return true when the count of type001 records changes from 2 to 1', () => { let mockRecords = [ { name: 'Barbara Gordon', type: 'type001' }, { name: 'Cassandra Cain', type: 'type001'} ] as unknown as Record []; expect(component.isLastRecord).toBe(false); component.records = mockRecords; expect(component.isLastRecord).toBe(false); component.records = [mockRecords.pop()]; expect(component.isLastRecord).toBe(true); }); // 失败的测试用例 // it('Should return false when the count of type001 records changes from 1 to 2', () => { // let mockRecords = [ // { name: 'Barbara Gordon', type: 'type001' } // ] as unknown as Record []; // expect(component.isLastRecord).toBe(false); // component.Records = mockRecords; // expect(component.isLastRecord).toBe(true); // const newRecord = {name: 'Cassandra Cain', type: 'type001'} as unknown as Record; // component.records.push(newRecord); // expect(component.isLastRecord).toBe(false); // }); }); })
问题原因与解决方案
失败原因
测试用例中使用component.records.push(newRecord)直接修改数组,不会触发records的setter方法。因为get records()返回的是私有变量_records的引用,直接修改数组内容不会触发setter的赋值逻辑,导致isLastRecord没有重新计算。
修改测试用例
要触发setter,必须重新给component.records赋值新数组,而不是修改现有数组的内容。同时修正测试中的拼写错误(component.Records改为component.records):
it('Should return false when the count of type001 records changes from 1 to 2', () => { let mockRecords = [ { name: 'Barbara Gordon', type: 'type001' } ] as unknown as Record[]; expect(component.isLastRecord).toBe(false); component.records = mockRecords; expect(component.isLastRecord).toBe(true); const newRecord = {name: 'Cassandra Cain', type: 'type001'} as unknown as Record; // 创建新数组并赋值,触发setter逻辑 component.records = [...mockRecords, newRecord]; expect(component.isLastRecord).toBe(false); });
是否需要Spy或模拟数据
- 这个场景不需要使用Spy,因为逻辑是通过setter的赋值触发的,只要保证每次更新
records时都是赋值新数组,就能触发setter中的计算逻辑。 - 其他测试用例目前运行正常,因为它们都是通过重新赋值数组来触发setter,所以不需要额外添加Spy或模拟数据。
内容的提问来源于stack exchange,提问作者Babulaas
相关产品推荐
相关产品推荐

