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

Angular12使用Jasmine Karma编写saveConversionRecords单元测试求助

单元测试编写方案

前置调整

  • 依赖服务打桩:不要在测试模块中引入真实的UserService和CookieService,避免触发真实HTTP请求、操作实际浏览器Cookie,使用Jasmine间谍对象替代真实服务
  • 私有方法调用:TypeScript不允许直接调用类的私有方法,测试时可以用// @ts-ignore注释忽略类型校验,也可以临时将方法改为public,测试完成后再改回私有

测试模块改造代码

把你原有测试代码的providers部分替换为以下内容:

// 提前定义间谍对象
let userServiceSpy: jasmine.SpyObj<UserService>;
let cookieServiceSpy: jasmine.SpyObj<CookieService>;

beforeEach(async(() => {
  // 构造服务间谍,指定要模拟的方法
  const userSpy = jasmine.createSpyObj('UserService', ['saveConversion']);
  const cookieSpy = jasmine.createSpyObj('CookieService', ['delete']);

  TestBed.configureTestingModule({
    imports: [ReactiveFormsModule, FormsModule,],
    declarations: [ LoginFormComponent ],
    providers: [
      AuthService,
      LoaderService,
      { provide: UserService, useValue: userSpy },
      { provide: CookieService, useValue: cookieSpy }
    ]
  })
  .compileComponents();

  // 注入间谍对象方便后续调用验证
  userServiceSpy = TestBed.inject(UserService) as jasmine.SpyObj<UserService>;
  cookieServiceSpy = TestBed.inject(CookieService) as jasmine.SpyObj<CookieService>;
}));

核心测试用例设计

总共覆盖2类核心场景:

场景1:无userId传入时,不触发后续逻辑

it('传入空userId时不执行保存和删除cookie操作', () => {
  // 构造模拟的cookie值
  const mockCookies = JSON.stringify([{lpVersion: 1, source: 'test'} as Conversion]);
  // 调用私有方法
  // @ts-ignore
  component.saveConversionRecords(mockCookies, '');

  // 验证两个依赖方法都没有被调用
  expect(userServiceSpy.saveConversion).not.toHaveBeenCalled();
  expect(cookieServiceSpy.delete).not.toHaveBeenCalled();
});

场景2:有userId传入时,所有逻辑正常执行

it('传入有效userId时执行全量逻辑', () => {
  // 模拟saveConversion返回空Observable
  userServiceSpy.saveConversion.and.returnValue(of(1));
  // 构造测试用Cookie数组,最后一项是我们要验证的对象
  const testLastCookie: Conversion = {lpVersion: 1, source: 'baidu', keyword: 'test'} as Conversion;
  const mockCookies = JSON.stringify([{lpVersion: 2} as Conversion, testLastCookie]);
  const testUserId = 'test_user_123';

  // @ts-ignore
  component.saveConversionRecords(mockCookies, testUserId);

  // 验证lpVersion被修改为3
  expect(testLastCookie.lpVersion).toBe(3);
  // 验证saveConversion被调用,参数符合预期
  expect(userServiceSpy.saveConversion).toHaveBeenCalledWith(testUserId, testLastCookie);
  // 验证Cookie被删除
  expect(cookieServiceSpy.delete).toHaveBeenCalledWith('conv');
});

注意事项

  • 需要提前从rxjs中导入of操作符,用来模拟Observable返回值
  • 如果需要验证HTTP请求的参数、路径正确性,可以单独给UserService的saveConversion方法编写服务层单元测试,引入HttpClientTestingModule即可,不需要和组件测试耦合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:24:02