angular - 如何使用 Angular 的 HttpTestingController 检查是否已向同一个 API 端点发出 2 个 HTTP 请求?

标签 angular unit-testing http jasmine angular-test

我正在使用 Angular 5 和 Jasmine 来测试我的 HTTP 服务。

我的 HTTP 服务将对同一端点进行 2 次 HTTP 调用,作为方法的一部分。我想检查该服务是否进行了 2 次 HTTP 调用。

已经有一个非常有用的 expectOne("route").flush([]); 方法,但理想情况下我想要 expectTwo("route").flush([]) ;expect("route", 2).flush([]);

这是一个示例测试:

it("getApprovers called twice with over 5 seconds apart makes two calls",
    () => {
        userService.getApprovers().subscribe(x => expect(x.length).toBe(0));

        setTimeout(() => userService.getApprovers().subscribe(x => expect(x.length).toBe(0)), 5001);

        // assert that 2 calls are made here
    });

有什么方法可以断言调用了 2 次?

提前致谢

最佳答案

使用 Jasmine,您可以spyOn 函数并使用 expect(spiedOnFunction.calls.count()).toEqual(something) 检查调用计数。

您想在 5 秒后再次测试调用,这恰好是 Jasmine 默认测试超时,因此 jasmine.DEFAULT_TIMEOUT_INTERVAL 必须在 中增加到超过 5 秒beforeEach.

最后,因为您正在使用带有 setTimeout 的异步调用,所以您必须在调用完成后测试预期。如果您在 setTimeout 完成之前调用您的 expects,您的测试将不会通过。以下是如何使用 Promiseasyncawait 来做到这一点。

// dummy code under test
const userService = {
  getApprovers: function() {
    // dummy function
  }
};

describe("Jasmine test with Promise, async, await, and over 5 seconds for async call", () => {
  beforeEach(() => {
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 6000;
  });

  it("getApprovers called twice with over 5 seconds apart makes two calls", async () => {
    // Arrange
    spyOn(userService, "getApprovers");

    // Act
    userService.getApprovers();
    await invokeFunctionAfterFiveSeconds(userService.getApprovers);

    // Assert
    expect(userService.getApprovers.calls.count()).toEqual(2);
  });
});

function invokeFunctionAfterFiveSeconds(func) {
  return new Promise(resolve => {
    setTimeout(() => {
      func();
      resolve();
    }, 5001);
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.3.14/polyfill.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.0.0/jasmine.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.0.0/jasmine-html.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.0.0/boot.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.0.0/jasmine.min.css" rel="stylesheet"/>

我不确定你对订阅和长度检查做了什么,所以我把它拿出来简化事情,但如果这对测试很关键,就把它加回来。

关于angular - 如何使用 Angular 的 HttpTestingController 检查是否已向同一个 API 端点发出 2 个 HTTP 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48986497/

相关文章:

unit-testing - 检查 IBOutlet 与 OCMock 的连接

c# - 当响应服务器不发回任何 HTTP header 时,如何使用 C# 接收 HTTP?

http - 使用分块传输编码时的 Grails 多个请求

angular - mat-select 中的动态禁用/启用无法正常工作

c# - 如何测试 Web API JSON 响应?

javascript - 单击 Angular 组件外部后无法删除事件框阴影

c++ - 在不同进程上运行 Boost 单元测试

http - 解析 "Connection" header 的 http 代理示例?

angular - 将值传递给组件时是否存在可选的 input() 条件?

javascript - 无法将 cx-media 组件与媒体容器一起使用