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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:42:15