【问题标题】:Angular mock multiple HTTP callsAngular 模拟多个 HTTP 调用
【发布时间】:2018-11-12 22:03:17
【问题描述】:

我有一项服务正在返回多个 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() 调用正常和门

错误:预期有一个条件匹配请求“匹配 URL:

 '/url/1", found none.

【问题讨论】:

  • 这方面有什么更新吗?

标签: angular typescript rxjs karma-jasmine angular-httpclient


【解决方案1】:

那是因为您使用 of 方法将 HttpClient 创建的可观察对象包装在新的可观察对象中。

通过做

joined$ = forkJoin(obs$(post1$),obs$(post2$))

注意:$ 代表 observable

你创建了一个新的 observable:

  • 订阅外部obs$
  • 等待他们完成,
  • 收集它们最后发出的值(在本例中为 post1$ 和 post2$)
  • 按照源流的顺序将收集的值作为数组返回

因为我们只订阅了外部obs$,所以您的测试失败了

'/url/1",没有找到。

由于我们从未订阅过内部 post$,这意味着请求没有发送。

将您的服务方法更改为:

addComments(){    
    const ob1 = this.http.post('/url/1');
    const ob2 = this.http.post('/url/2');

    return Observable.forkJoin(ob1,ob2);
 }

【讨论】:

  • 我更新了我的代码。它仍然抛出同样的错误。
【解决方案2】:

我遇到了类似的问题,我使用 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();

  })));

【讨论】:

  • 我目前使用的是 Angular 11,我可以确认这也适用于我
【解决方案3】:

在调用 expectOne 之前,您需要调用 addComments 并订阅返回的 observable。只有订阅时才会触发httpClient 请求

这是导致测试失败的核心问题

顺便说一句,你不使用 fakeAsync 是对的,因为使用 HttpClientTestingModule 是同步的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多