我想测试一个管道HttpClient调用,但http调用似乎没有及时完成,也没有响应。
配置.service.ts
public loadData() {
return this.configurationService.getAppConfig().pipe(
switchMap(appConfig => this.http.get<string[]>("url"))
);
}
configuration.service.spec.ts
let service: CustomService;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
CustomService,
{ provide: ConfigurationService, useClass: MockedConfigurationService }
],
imports: [HttpClientTestingModule],
});
httpTestingController = TestBed.get(HttpTestingController);
service = TestBed.get(ConfigurationService);
});
it("should make a get request for loadData", () => {
service.loadData().subscribe(data => {
// This is not called
console.log(data);
});
const req = httpTestingController.expectOne("url");
req.flush(["my.data"]);
expect(req.request.method).toEqual("GET");
httpTestingController.verify();
});
如果我只是像一样返回请求,一切都很好
return this.http.get<string[]>("url");
我也尝试过使用手动创建/完成的Observables,但没有订阅httpClient:
const appConfig$ = this.configurationService.getAppConfig();
return new Observable(observer => {
appConfig$.subscribe(appConfig => {
this.http.get<string[]>("url").subscribe(
result => {
observer.next(result);
observer.complete();
}
);
});
});
我做错了什么?在httpClient能够完成之前,测试用例似乎已经完成。
我认为您的MockedConfigurationService
不准确。我们能看到吗?
尝试
import { of } from 'rxjs';
....
class MockedConfigurationService {
getAppConfig() {
return of('hello world'); // or whatever you would like.
}
}
同时我想明白了。
问题是,多个异步调用导致http内容刷新比调用本身运行得更早。
所以我使用的是fakeAsync,在刷新真实数据之前有一个flush((,它让httpClient首先打开请求。
it("should make a get request for loadData", fakeAsync(() => {
service.loadData().subscribe(data => {
// This is called
console.log(data);
});
flush();
const req = httpTestingController.expectOne("url");
req.flush(["my.data"]);
expect(req.request.method).toEqual("GET");
httpTestingController.verify();
}));
也许还有更好的解决方案,我对此持开放态度。