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

如何用Jasmine测试URL调用并验证Promise返回值?

如何用Jasmine正确测试Angular的getImageBlob方法

你的原方法实现

getImageBlob(docLink: string): Promise<Blob> {
  const httpHeaders = new HttpHeaders({
    'TOKEN': token,
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
  });
  return this.http.get<Blob>(docLink, { headers: httpHeaders, responseType: 'blob' as 'json' }).toPromise();
}

原测试代码的问题

你写的测试存在几个明显问题:

  • 错误地在catch中断言错误状态为200,200是成功状态,不会进入catch分支
  • 没有验证HTTP请求是否真的调用了指定URL
  • 未正确处理Promise的异步逻辑,可能导致测试在断言执行前就结束,断言不生效

正确的测试方案

下面是完整的测试示例,包含验证URL调用和验证Promise返回值两部分逻辑,使用Angular官方的HttpClientTestingModule来mock HTTP请求:

import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
// 导入你的服务类和TokenService依赖

describe('你的服务类名称', () => {
  let service: 你的服务类名称;
  let httpTestingController: HttpTestingController;
  const mockImageLink = 'https://example.com/test-image.png';
  const mockToken = 'xyzToken';

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        你的服务类名称,
        // Mock TokenService,返回预设的token
        { provide: TokenService, useValue: { getToken: () => mockToken } }
      ]
    });
    service = TestBed.inject(你的服务类名称);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  // 每次测试后验证没有未处理的HTTP请求,避免泄漏
  afterEach(() => {
    httpTestingController.verify();
  });

  // 测试:是否调用了指定的URL和正确的请求方法、请求头
  it('should send GET request to the specified URL with correct headers', () => {
    service.getImageBlob(mockImageLink);

    // 捕获匹配mockImageLink的HTTP请求
    const req = httpTestingController.expectOne(mockImageLink);
    // 验证请求方法是GET
    expect(req.request.method).toBe('GET');
    // 验证请求头包含正确的TOKEN
    expect(req.request.headers.get('TOKEN')).toBe(mockToken);
  });

  // 测试:请求成功时是否返回正确的Blob
  it('should return a Blob when request succeeds', async () => {
    // 创建测试用的Blob
    const mockBlob = new Blob(['fake image content'], { type: 'image/png' });

    // 调用方法,获取Promise对象
    const resultPromise = service.getImageBlob(mockImageLink);

    // 匹配请求并返回模拟的Blob响应
    const req = httpTestingController.expectOne(mockImageLink);
    req.flush(mockBlob);

    // 等待Promise完成,验证返回值
    const returnedBlob = await resultPromise;
    expect(returnedBlob instanceof Blob).toBe(true);
    expect(returnedBlob.type).toBe('image/png');
    // 可选:验证Blob内容
    const blobText = await returnedBlob.text();
    expect(blobText).toBe('fake image content');
  });

  // 测试:请求失败时是否正确抛出错误
  it('should reject with error when request fails', async () => {
    const mockError = { status: 404, statusText: 'Not Found' };

    const resultPromise = service.getImageBlob(mockImageLink);

    // 匹配请求并返回模拟错误
    const req = httpTestingController.expectOne(mockImageLink);
    req.error(new ErrorEvent('Request failed'), mockError);

    // 验证Promise被拒绝且错误状态正确
    try {
      await resultPromise;
      fail('Expected promise to be rejected');
    } catch (err) {
      expect(err.status).toBe(404);
      expect(err.statusText).toBe('Not Found');
    }
    // 也可以用Jasmine的expectAsync简化
    // await expectAsync(resultPromise).toBeRejectedWithError('Not Found');
  });
});

关键注意事项

  • 用HttpClientTestingModule来mock HTTP请求,HttpTestingController可以捕获并验证请求的细节
  • 使用async/await处理Promise的异步逻辑,确保断言在Promise完成后执行
  • expectOne方法可以精准匹配目标URL,确保请求调用了正确的地址
  • 每次测试后用verify()检查是否有未处理的请求,避免测试污染
  • 分别测试成功、失败两种场景,覆盖完整逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 11:57:48