I have one service which is returning the forkjoin of multiple http calls. I wanted to test this scenario.
class CommentService{
addComments(){
let ob1 = Observable.of({});
let ob2 = Observable.of({});
if(any condition)
ob1 = {this.http.post('/url/1')};
if(any condition)
ob2 = {this.http.post('/url/2'};
return Observable.forkJoin(ob1,ob2)
}
}
Above is my service class. How can i mock the http calls.
describe("CommentService", () => {
let httpClient: HttpClient;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule, HttpClientTestingModule],
providers: [CommentService]
});
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
});
it('addComments() call with normal and gate', inject([CommentService], (service: CommentService) => {
let cmts = service.addComments();
const reqGateComment = httpTestingController.expectOne('/url/1');
expect(reqGateComment.request.method).toEqual('POST');
const reqFactComment = httpTestingController.expectOne('/url/2');
expect(reqFactComment.request.method).toEqual('POST');
reqGateComment.flush({});
reqFactComment.flush({});
httpTestingController.verify();
cmts.subscribe(results=>{
expect(results.length).toEqual(2);
});
}));
});
I am getting the below test fail. CommentService addFactsAndComments() call with normal and gate
Error: Expected one matching request for criteria "Match URL:
'/url/1", found none.
I had a similar problem and I solved it using fakeAsync.
it('addComments() call with normal and gate', fakeAsync( inject([CommentService], (service: CommentService) => {
service.addComments().subscribe(results=>{
expect(results.length).toEqual(2);
});
const reqGateComment = httpTestingController.expectOne('/url/1');
expect(reqGateComment.request.method).toEqual('POST');
reqGateComment.flush({});
tick(10000);
const reqFactComment = httpTestingController.expectOne('/url/2');
expect(reqFactComment.request.method).toEqual('POST');
reqFactComment.flush({});
httpTestingController.verify();
})));
Thats because you are wrapping the observables created by the HttpClient
in new ones by using the of
method.
By doing
joined$ = forkJoin(obs$(post1$),obs$(post2$))
Note: $ stands for observable
You create a new observable that:
obs$
Because we only subscribed to the outer obs$
, your test is failing with
'/url/1", found none.
As we never subscribed to the inner post$, meaning that the requests werent sent.
Change your service method to:
addComments(){
const ob1 = this.http.post('/url/1');
const ob2 = this.http.post('/url/2');
return Observable.forkJoin(ob1,ob2);
}
You need to call addComments
and subscribe to the returned observable before you invoke expectOne
. Only on subscription will the httpClient
requests be triggered
That's the core issue here that's causing the test failure
You're right not to use fakeAsync btw as using HttpClientTestingModule is synchronous
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.