Angular 在带有缓存的自定义API服务中模拟HttpClient
我试图用Jasmine编写一些测试,我想在我的定制api服务中模拟HttpClient,但我得到了一个错误。具体来说,我认为这是因为我是如何编写API服务的。我调用端点,然后将结果缓存到行为主题中。我返回行为主题,而不是http请求可见 这是我的服务代码: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
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();
});