You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Angular 5 HTTP单元测试报错Expected no open requests, found 1怎么解决?

解决Angular 5 HTTP单元测试中的Error: Expected no open requests, found 1问题

嘿,这个问题我太熟了!在Angular的HTTP单元测试里碰到这个错误,本质就是你的测试用例跑完后,还有一个HTTP请求没被HttpTestingController处理掉。别慌,咱们一步步来解决:

问题根源

Angular的HttpClientTestingModuleHttpTestingController来拦截所有真实的HTTP请求,转而用模拟响应代替。但它有个严格的规则:每个被拦截的请求都必须被显式匹配并处理,否则测试结束时就会抛出这个“还有未完成请求”的错误。

结合你的代码修复

从你给出的测试代码片段来看,你在测试DangerService的GET请求,那咱们把缺失的关键步骤补上:

1. 确保注入HttpTestingController

首先在测试块里注入控制器实例,方便后续处理请求:

import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { DangerService } from './danger.service';
import { DangerFlag } from '../danger.model';

describe('DataService Tests', () => {
  let dataService: DangerService;
  let httpTestingController: HttpTestingController; // 新增控制器实例

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [DangerService]
    });

    // 获取服务和控制器实例
    dataService = TestBed.inject(DangerService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  // 测试用例写在这里
});

2. 完整的GET请求测试示例

每个测试用例都要遵循“调用服务 -> 匹配请求 -> 返回模拟数据 -> 验证请求完成”的流程:

it('should fetch danger flags successfully via GET', () => {
  // 1. 准备模拟数据
  const mockDangerFlags: DangerFlag[] = [
    { id: 1, name: 'High Risk', level: 3 },
    { id: 2, name: 'Medium Risk', level: 2 }
  ];

  // 2. 调用服务的GET方法(必须订阅,否则请求不会触发)
  dataService.getDangerFlags().subscribe(flags => {
    expect(flags).toEqual(mockDangerFlags); // 验证返回数据
  });

  // 3. 匹配发送的请求(替换成你实际的API地址,支持正则)
  const req = httpTestingController.expectOne('/api/danger-flags');
  expect(req.request.method).toBe('GET'); // 验证请求方法是否正确

  // 4. 返回模拟响应
  req.flush(mockDangerFlags);

  // 5. 全局验证所有请求都已处理(关键!)
  httpTestingController.verify();
});

3. 避免踩坑的小技巧

  • 全局验证请求完成:可以把httpTestingController.verify()放在afterEach里,确保每个测试用例结束后都检查有没有遗漏的请求:
    afterEach(() => {
      httpTestingController.verify();
    });
    
  • URL匹配要准确:如果你的请求有动态参数(比如/api/danger-flags?id=1),可以用正则表达式匹配:httpTestingController.expectOne(/\/api\/danger-flags/)
  • 别忘了订阅Observable:Angular的HTTP请求是冷Observable,只有订阅后才会真正发送请求,没订阅的话控制器也抓不到请求哦。

总结

这个错误就是在提醒你:“喂,还有个HTTP请求没处理呢!”只要确保每个请求都被expectOne匹配、flush返回数据,最后用verify检查,问题就能解决啦。

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

火山引擎 最新活动