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

Angular+Jest单元测试subscribe方法报错:Cannot spyOn原始值

解决Angular Jest测试中Cannot spyOn on a primitive value; undefined given报错问题

问题根源

你触发的报错核心原因是:在TestBed配置阶段,mockUserService初始值为undefined,你用useValue: mockUserService注入的是一个无效的原始值,后续尝试对这个undefined对象的getUsers方法做spy操作时,就会抛出该错误。

修复步骤

1. 提前初始化有效的mock服务对象

在测试代码最开始,把mockUserService初始化为包含getUsers方法的模拟对象(或者至少是一个空对象),避免注入undefined。

2. 调整TestBed配置逻辑

确保providers中注入的是已经初始化好的mock对象,而不是未定义的变量。

3. 补全组件依赖的初始化

原方法中用到了this.form?.getRawValue(),如果组件的form未初始化,会导致后续方法调用异常,需要在测试前给form赋值。

完整修复后的测试代码

describe('UserComponent', () => {
  let component: UserComponent;
  let fixture: ComponentFixture<UserComponent>;
  // 提前初始化mock服务,避免undefined
  let mockUserService: Partial<UserService> = {
    getUsers: jest.fn()
  };

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [UserComponent],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      providers: [
        { provide: UserService, useValue: mockUserService },
      ],
      imports: [
        HttpClientTestingModule,
        ReactiveFormsModule,
        RouterTestingModule,
        MatDialogModule,
        BrowserAnimationsModule
      ]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(UserComponent);
    component = fixture.componentInstance;
    mockUserService = TestBed.inject(UserService);
    // 初始化组件的form,避免getRawValue()返回undefined
    component.form = new FormGroup({});
    // 如果需要验证agGrid的setRowData,也可以初始化agGrid对象
    component.agGrid = { api: { setRowData: jest.fn() } };
  });

  it('should execute processing methods and call user service when doSearch runs', () => {
    const mockresponse = {
      content: [{
        businessUnitId: '0800',
        firstName: 'teste',
        lastName: 'lastteste',
        mail: 'teste@gmail.com',
        isActive: true,
      }],
    };
    const spysplit = jest.spyOn(component, 'splitStringToGetOnlyTheId');
    const spycheck = jest.spyOn(component, 'onCheckEmptyFieldsAndReplaceNull');
    const spyService = jest.spyOn(mockUserService, 'getUsers').mockReturnValue(of(mockresponse));

    component.doSearch();

    expect(spysplit).toHaveBeenCalled();
    expect(spycheck).toHaveBeenCalled();
    expect(spyService).toHaveBeenCalled();
    // 额外验证subscribe内的状态更新逻辑
    expect(component.isLoading).toBe(false);
    expect(component.isShowingTable).toBe(true);
    expect(component.dataSource).toEqual(mockresponse.content);
    expect(component.agGrid?.api.setRowData).toHaveBeenCalledWith(mockresponse.content);
  });
});

额外说明

  • 如果你不需要验证agGrid的方法,可以去掉对应的初始化和断言;
  • 原doSearch方法的subscribe没有处理错误分支,如果需要覆盖错误场景,可以给mock的getUsers返回throwError,并验证状态是否正确更新。

内容的提问来源于stack exchange,提问作者unitestangular

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:18:18