【问题标题】:How to test multiple requests in pipeline in Angular?如何在 Angular 的管道中测试多个请求?
【发布时间】:2020-06-24 20:09:05
【问题描述】:

我想测试在管道内完成的 3 个请求。简化示例:

    httpClient.get<Data[]>(testUrl)
      .pipe(
        mergeMap(() => range(0, 2)),
        mergeMap(() => httpClient.get<Data[]>(testUrl)),
      )

我正在使用official recommendation: HttpTestingController。如果我用httpTestingController.match 一个接一个地提出请求,它工作得很好。但是,这不是我真正的应用程序的编写方式。它正在使用管道。

    let testData: Data[] = [
      { name: 'bob' }, { name: 'carol' },
      { name: 'ted' }, { name: 'alice' }
    ];

    // Make three requests in a row
    httpClient.get<Data[]>(testUrl)
      .subscribe(d => expect(d.length).toEqual(0, 'should have no data'));

    httpClient.get<Data[]>(testUrl)
      .subscribe(d => expect(d).toEqual([testData[0]], 'should be one element array'));

    httpClient.get<Data[]>(testUrl)
      .subscribe(d => expect(d).toEqual(testData, 'should be expected data'));

    // get all pending requests that match the given URL
    const requests = httpTestingController.match(testUrl);
    expect(requests.length).toEqual(3);

    // Respond to each request with different results
    requests[0].flush([]);
    requests[1].flush([testData[0]]);
    requests[2].flush(testData);

如何使 httpTestingController.match 在管道内处理多个 HTTP 请求?

这是我迄今为止尝试过的,这里是reproducible example

    httpClient.get<Data[]>(testUrl)
      .pipe(
        mergeMap(() => range(0, 2)),
        mergeMap(() => httpClient.get<Data[]>(testUrl)),
      )
      .subscribe(d => expect(d.length).toEqual(0, 'should have no data')); 

    const requests = httpTestingController.match(testUrl);
    console.log({requests}); // <--- why only one instead of 3??

    requests[0].flush([]);
    // requests[1].flush([]); // This is undefined. How do I flush the other two requests?
    // requests[2].flush([]);  // undefined. 

    // Error: Expected no open requests, found 2: GET /data, GET /data

https://stackblitz.com/edit/angular-http-testing2?file=src%2Ftesting%2Fhttp-client.spec.ts

【问题讨论】:

  • 也许你正在寻找 rxjs forkJoin - “‘forkJoin’ 等待每个 HTTP 请求完成” - medium.com/@swarnakishore/…
  • @bob.mazzo 是的,我实际上在我的真实应用程序上使用了 forkJoin。但是为了简化问题并提供一个最小的可重现示例,我正在使用 mergeMap。无论如何都失败了:(。我不知道如何使它与httpTestingController.match 或多个httpTestingController.expectOne 一起工作。有什么想法吗?你可以分叉 Stackblitz 看看你能不能让它工作

标签: angular unit-testing testing httptestingcontroller


【解决方案1】:

文档说:

// get all pending requests that match the given URL
const requests = httpTestingController.match(testUrl);

所以你收到了一个请求,因为只有一个处于待处理状态。当第一个请求完成时,Rest 将变为挂起状态。所以要逐步测试它。

let sentCount = 1;
httpClient.get<Data[]>(testUrl)
  .pipe(
    mergeMap(() => range(0, 2)),
    tap(() => sentCount++),
    mergeMap(() => httpClient.get<Data[]>(testUrl)),
  )
  .subscribe(d => expect(d.length).toEqual(0, 'should have no data')); 

const requests = httpTestingController.match(testUrl);
expect(sentCount).toBe(1);
requests[0].flush([]);
expect(sentCount).toBe(3);
httpTestingController.match(testUrl);

【讨论】:

    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多