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

Jasmine spyOn依赖注入服务单元测试断言失败问题求助

Jasmine测试构造函数注入依赖问题排查与修复

核心问题分析

第二个测试断言失败的直接原因是你mock了被测方法getAccount本身:

spyOn(service, 'getAccount').and.returnValue(Promise.resolve(accountData));

这段代码直接替换了AccountService.getAccount的原始实现,导致原方法里的权限校验逻辑(调用authorityService.hasAuthority)完全没有被执行,自然触发hasAuthority从未被调用的断言失败。

解决方案

要测试getAccount的真实逻辑,不能mock它本身,而是要mock它的依赖(ApiService的get方法),同时保持对authorityService.hasAuthority的spy,确保权限校验逻辑被执行。

修正后的测试代码

it('should return the account if the permissions are set', async () => {
  const accountData = { firstName: 'Test', lastName: "tester" } as Account;
  
  // 1. 保留对权限服务的spy,让它返回true
  spyOn(authorityServiceDependency, 'hasAuthority').withArgs(Authority.PERM_ACCOUNT_READ).and.returnValue(true);
  
  // 2. 调用被测方法
  const account = await service.getAccount();
  
  // 3. 验证权限校验被触发
  expect(authorityServiceDependency.hasAuthority).toHaveBeenCalledWith(Authority.PERM_ACCOUNT_READ);
  
  // 4. 拦截ApiService的请求并返回预设数据
  const req = httpTestingController.expectOne('/admin/rest/account');
  expect(req.request.method).toBe('GET');
  req.flush(accountData);
  
  // 5. 验证返回结果正确
  expect(account).not.toBeNull();
  expect(account?.firstName).toEqual("Test");
  expect(account?.lastName).toEqual("tester");
  
  // 确保所有请求都被处理
  httpTestingController.verify();
});

关键调整说明

  • 移除了对service.getAccount的spy,让原始方法逻辑完整执行
  • 使用async/await处理异步逻辑,避免回调嵌套导致的断言时机问题
  • 用httpTestingController.expectOne精准拦截API请求,返回预设的账户数据
  • 增加httpTestingController.verify()确保没有未处理的请求

关于Stub类的使用说明

你当前用authorityServiceStub类替换真实服务的方式是正确的,不过也可以用更简洁的useValue方式直接创建对象,无需定义类:

{
  provide: AuthorityService,
  useValue: {
    hasAuthority: () => false
  }
}

两种方式都能达到替换依赖的目的,根据代码复杂度选择即可。

额外测试注意事项

  • 测试异步方法时,优先使用async/await,代码更易读且能确保断言在异步操作完成后执行
  • 不要mock被测对象的方法,要mock它的依赖服务,这样才能测试真实业务逻辑
  • 每次测试后,HttpTestingController会自动清理,但主动调用verify()能提前发现未处理的请求问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 09:10:12