我有一个服务正在返回多个http调用的forkjoin。我想测试这个场景。
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)
}
}
以上是我的服务类。我怎么能模拟http调用。
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);
});
}));
});
我得到以下测试失败。 CommentService addFactsAndComments()调用normal和gate
错误:符合条件的匹配请求“匹配网址:
'/url/1", found none.
答案 0 :(得分:1)
我遇到了类似的问题,我使用 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();
})));
答案 1 :(得分:0)
这是因为您使用HttpClient
方法将of
创建的可观察对象包装在新的joined$ = forkJoin(obs$(post1$),obs$(post2$))
中。
通过
obs$
注意:$代表可观察的
您创建了一个新的observable:
obs$
因为我们只订阅了外部addComments(){
const ob1 = this.http.post('/url/1');
const ob2 = this.http.post('/url/2');
return Observable.forkJoin(ob1,ob2);
}
,所以您的测试失败了
'/ url / 1“,找不到。
因为我们从未订阅内部帖子$,这意味着请求未被发送。
将您的服务方式更改为:
TCPDF
答案 2 :(得分:0)
我最近遇到了同样的问题,这就是我解决的方法。 首先,我不得不忘记HttpTestingController和HttpClientTestingModule并编写自己的模拟实现类。以下是我在Message控制器中测试多个请求的解决方案,该控制器使用forkJoin处理多个请求(MessageService中的getPosts,getComments)。
class MockMessageService {
getPosts() {
return of([{ id: 1, title: "Post 1", body: "Post Content 1" }, { id: 2, title: "Post 2", body: "Post Content 2" }]);
}
getComments() {
return of([{ id: 1, postId:1, name: "quo vero", body: "est natus enim nihil est" }, { id: 2, postId:2, name: "id labore", body: "quia molestiae reprehenderit" }]);
}
}
describe('MessageComponent', () => {
let component: MessageComponent;
let service: MessageService;
let el: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
MessageComponent
],
providers: [{ provide: MessageService, useClass: MockMessageService }]
});
fixture = TestBed.createComponent(MessageComponent);
component = fixture.componentInstance;
el = fixture.debugElement;
service = el.injector.get(MessageService);
});
it('should get message posts and comments on Oninit', () => {
spyOn(service, 'getPosts').and.callThrough();
spyOn(service, 'getComments').and.callThrough();
component.ngOnInit();
expect(service.getPosts).toHaveBeenCalled();
expect(service.getComments).toHaveBeenCalled();
});
});
答案 3 :(得分:0)
在调用 addComments
之前,您需要调用 expectOne
并订阅返回的 observable。只有在订阅时才会触发 httpClient
请求
这是导致测试失败的核心问题
顺便说一句,您不使用 fakeAsync 是对的,因为使用 HttpClientTestingModule 是同步的