使用Jasmine和waiting测试基于HTTP的异步函数:预期有一个匹配的"...... "标准请求,没有找到。

问题描述 投票:0回答:1

WHAT: 测试一个使用 await 的异步函数。

使用:Angular 9, Jasmine 3.4.0。

最少的代码重现。StackBlitz

我有一个这样的函数。注意,它必须等待this.getHeaders()。每当我去掉 await,用一些同步的实现代替 getHeaders()的实现时,测试就会成功运行。

请问正确的测试方法是什么?

private async loadUserData() {
    // Try to remove await - the test runs successfully
    //const headers = this.getHeaders();
    const headers = await this.getHeaders();
    return this.httpClient
      .get<UserData>(window.location.origin + '/12345', { headers })
      .toPromise()
      .then((data) => {
        this.userData = data;
      })
      .catch((e) => {
        console.log('Oh noooo...');
      });
  }

我已经尝试过了。

  • 可能是StackBitz中的url不正确,但在本地测试时,我确定是正确的,所以这应该不是根本原因。
  • 不知道 fakeAsync()是否会有帮助--"纯 "http测试是有效的...。

而不是一个二重的。

angular testing async-await jasmine
1个回答
1
投票

你已经很接近了。你的测试现在结构正确,但你需要一些由Angular提供的测试工具,以确保你的Promises以正确的顺序解决,你的期望是正确的。

最终,问题与Angular区域有关。因为你在你的服务中构建了承诺,而这个承诺的解析必须在一个外发请求发生之前发生。你调用 loadUserData 在你的测试中,然后在下一行你写一个断言,说 "确保这个请求发生了,如果没有,那就是一个错误"。当你在写头检索函数时,你不使用异步基元(如 PromiseObservable)这个请求会 "立即 "发生。但是当你使用 Promise,没有请求 "立即 "发生。相反,它必须先解析你的头检索函数。

幸运的是,你的测试失败只是测试环境的一个幻象功能,而不是你的实现中的一个bug。就像我说的,Angular给你提供了一些测试工具,以确保你可以在写断言之前 "刷新 "所有待定的承诺。

import { fakeAsync,  tick } from '@angular/core/testing';

// instead of using `done`, which is just fine btw, we wrap our test function
// in fakeAsync(). This let's us have fine grained control over stepping through
// our code under test
it('should return user data on success', fakeAsync(() => {
  const mockUserData : UserData = {
    name: 'John',
      surname: 'Do',
      id: '12345'
    };

    (service as any).loadUserData().then(() => {
      expect((service as any).userData).toEqual(mockUserData);
      //expect(req.request.method).toEqual('GET');
    });

    // tick() steps through the next round of pending asynchronous activity
    // this will also step through 'setTimeout' and 'setInterval' code
    // you may have in your service, as well as Observable code
    tick();
    const req = httpTestingController.expectOne(
      'https://testing-qh48mg.stackblitz.io/12345',
    );
    req.flush(mockUserData);
}));

更新了 叠加闪电战. 文件 fakeAsync. 关于在Angular中使用Http代码测试的相关问题。tick.

© www.soinside.com 2019 - 2024. All rights reserved.