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

如何通过Jasmine测试用例‘should recover on fetch error’

问题根因分析
  • 你没有对fetch做模拟,第一个指向/recordszzz的请求实际会返回404或跨域错误,如果你的retrieve()函数没有对fetch的异常做捕获处理,第一个retrieve()调用返回的Promise会变成rejected状态,根本不会执行后续的check回调,自然不会触发你预期的console.log调用,所以第一个断言Expected spy log to have been called会报错。
  • 你用console.log的调用状态作为错误是否触发的判断依据完全不可靠:如果业务代码的错误分支用的是console.error打印日志、或者根本没打日志,都会触发断言失败;你手动加了console.log后如果正常分支也加了日志,第二个Expected spy log to not be called自然也会报错。
  • 直接修改window.path会产生全局副作用,未重置的情况下会影响其他测试用例的执行结果。
修复方案
  1. 优先使用Jasmine的fetch mock能力模拟接口返回,不要依赖真实后端服务的可用性,直接控制第一个请求返回异常、第二个请求返回正常数据。
  2. 移除对console.log的断言,改为直接判断retrieve()的返回状态、或者监听fetch的调用情况作为判断依据。

修正后的测试代码示例

it('should recover on fetch error', function(done){
  // 先存下原始path,测试结束后重置,避免副作用
  const originalPath = window.path;
  window.path = "http://localhost:3000/recordszzz";

  // 模拟fetch的返回:第一个调用返回错误,第二个调用返回正常数据
  spyOn(window, 'fetch').and.callFake((url) => {
    if (url.includes('recordszzz')) {
      return Promise.reject(new Error('Fetch failed'));
    }
    return Promise.resolve({
      json: () => Promise.resolve({/* Object here */})
    });
  });

  // 错误分支的回调
  function handleFirstError(err) {
    // 切换为正常接口地址
    window.path = "http://localhost:3000/records";
    // 第二次调用retrieve,验证可以正常返回
    retrieve().then(function(output){
      const expected = {/* Object here */};
      expect(output).toEqual(expected);
      // 重置全局变量
      window.path = originalPath;
      done();
    }).catch(done.fail); // 第二次调用失败的话直接标记测试失败
  }

  // 第一次调用,预期进入catch回调
  retrieve().catch(handleFirstError);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:15:05