如何对内部订阅HTTP请求、未返回Observable的Angular服务进行单元测试?
如何测试未返回Observable的Angular服务方法
咱先理清楚这个方法的逻辑:它内部发起HTTP请求,拿到响应后把数据传给BehaviorSubject,但自己不返回任何Observable。那测试的核心就落在两个关键点上——请求有没有发对,数据有没有正确流到data$里。下面是具体的测试方案:
测试前的准备
首先你需要用到Angular测试套件里的HttpClientTestingModule和HttpTestingController,它们能帮我们模拟HTTP请求,不用真的调用后端接口。
1. 测试HTTP请求是否正确发起
第一个测试点要确认:调用getDatas()时,是不是真的向预期的URL发起了GET请求。
import { TestBed } from '@angular/core/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { YourService } from './your.service'; // 替换成你的服务路径 describe('YourService', () => { let service: YourService; let httpMock: HttpTestingController; const testUrl = 'your-target-url'; // 替换成实际的URL beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [YourService] }); service = TestBed.inject(YourService); httpMock = TestBed.inject(HttpTestingController); }); afterEach(() => { // 确保所有HTTP请求都被处理,避免内存泄漏 httpMock.verify(); }); it('should send a GET request to the correct URL when getDatas is called', () => { // 调用要测试的方法 service.getDatas(); // 检查是否有符合条件的请求发出 const req = httpMock.expectOne(testUrl); // 验证请求方法是GET expect(req.request.method).toBe('GET'); // 模拟后端返回数据 req.flush({ id: 1, name: 'test data' }); }); });
2. 测试BehaviorSubject是否正确接收数据
接下来要验证:当HTTP请求返回数据后,data$这个BehaviorSubject能不能正确拿到数据。
it('should emit the response data to data$ when getDatas succeeds', (done) => { const testData = { id: 1, name: 'test data' }; // 订阅data$,等待数据到来 service.data$.subscribe((data) => { // 断言拿到的数据和模拟返回的一致 expect(data).toEqual(testData); done(); // 告诉测试框架异步操作完成 }); // 调用方法触发请求 service.getDatas(); // 模拟请求返回 const req = httpMock.expectOne(testUrl); req.flush(testData); });
小提示:修复原服务的一个小问题
注意哦,你的原服务里写了this.data$.emit(response),但BehaviorSubject的触发方法是next(),不是emit()(emit是EventEmitter的方法)。所以原服务的代码要改成:
this.data$.next(response);
不然数据根本发不出去,测试也会失败。
内容的提问来源于stack exchange,提问作者Zuckjet
相关产品推荐
相关产品推荐

