Angular 在带有缓存的自定义API服务中模拟HttpClient

Angular 在带有缓存的自定义API服务中模拟HttpClient,angular,jasmine,Angular,Jasmine,我试图用Jasmine编写一些测试,我想在我的定制api服务中模拟HttpClient,但我得到了一个错误。具体来说,我认为这是因为我是如何编写API服务的。我调用端点,然后将结果缓存到行为主题中。我返回行为主题,而不是http请求可见 这是我的服务代码: getData(binnum, xaxis, yaxis, numLines, selectionId, zoom = false) { let key = "x" + xaxis + "y" + yaxis + "bin" + bin

我试图用Jasmine编写一些测试,我想在我的定制api服务中模拟HttpClient,但我得到了一个错误。具体来说,我认为这是因为我是如何编写API服务的。我调用端点,然后将结果缓存到行为主题中。我返回行为主题,而不是http请求可见

这是我的服务代码:

getData(binnum, xaxis, yaxis, numLines, selectionId, zoom = false) {
   let key = "x" + xaxis + "y" + yaxis + "bin" + binnum + "lines" + numLines;

   let cachedItem = this.cache[key];
   if (cachedItem != null) {
     console.log("cached item");
     return cachedItem.bs;
   }

   let bs = new BehaviorSubject<any>(null);
   this.binCache[key] = { bs: bs, ts: new Date().getTime() };

   let url = environment.apiEndpoint + 'bins?binnum=' + binnum + '&xaxis=' + xaxis + '&yaxis=' + yaxis;

   let obsv = this.http.get(url);
   obsv.subscribe((data: Array<any>) => {
     bs.next(data);
   })
   return bs;
 }
我得到一个错误: 应为条件“匹配方法:GET,URL:(any)”提供一个匹配请求,但未找到任何匹配请求。

如果我只模拟HttpClient,它可以工作:

it(`should issue a request`,
   async(
      inject([HttpClient, HttpTestingController], (http: HttpClient, backend: HttpTestingController) => {
         http.get('/foo/bar').subscribe();
         backend.expectOne({
            method: 'GET'
         });
      })
   )
 );

如何在CustomDataService中模拟http请求?我需要将API服务与缓存代码分离吗?

上面建议重构我的代码,以便使用缓存服务和HttpInterceptor来管理它。不幸的是,我只需要缓存某些API调用,而拦截器会截获所有调用。我不想在拦截器中编写代码检查路由

我最初的解决方案是按照类似的方式建模的。因此,在我的解决方案中,我将API调用提取到上面的getData()函数使用的自己的服务中。我现在可以模拟HttpClient了

我不熟悉Angular的测试,但找到了我最初想要的答案:一种模拟后端调用并返回自定义数据的方法。以下是我写的测试:

it('Mocking a call to the backend', () => {

 // spyOn lets you mock a function call return a mock data
 spyOn(myService, 'getData').and.returnValue(of({ test: 2 }));
 renderManager.calculateThings(myService);

 // Check that it was called
 expect(myService.getData).toHaveBeenCalled();

});

我知道通过函数传递API服务有点奇怪,但我的场景保证了这一点。

该资源没有帮助。正如我之前所说的,我能够单独模拟HttpClient来工作。我的具体问题是为什么它不能与我的缓存一起工作。我已经编辑了我的问题,我建议你在很大程度上重构你的代码,因为你的目的是使服务可测试;将缓存提取到一个自包含的服务中,通过HttpInterceptor进行管理,不要在服务调用中订阅。一旦你做到这一点,你的代码的可测试性就会提高。这是有意义的。谢谢
it('Mocking a call to the backend', () => {

 // spyOn lets you mock a function call return a mock data
 spyOn(myService, 'getData').and.returnValue(of({ test: 2 }));
 renderManager.calculateThings(myService);

 // Check that it was called
 expect(myService.getData).toHaveBeenCalled();

});