【问题标题】:Angular - Testing async function with multiple http requestAngular - 使用多个 http 请求测试异步功能
【发布时间】:2026-01-26 10:05:02
【问题描述】:

我有这个登录功能,我想测试一下。但是我收到一个错误“异步回调未在 5000 毫秒内调用”

public async Login(email: string, password: string): Promise<any> {
    const body = { email, password };
    await this.getCSRFToken().toPromise();
    return this.http
      .post<any>(this.baseUrl + 'login', body)
      .pipe(
        tap(data => {
          this.user = data;
          return this.user;
        })
      )
      .toPromise();
  }

我的测试:

it('should login', (done) => {
    const service: AuthenticationService = TestBed.get(AuthenticationService);
    const http = TestBed.get(HttpTestingController);
    let userResponse;

    service.Login('email', 'password').then((response) => {
      userResponse = response;
    });

    http.expectOne((req) => {
      return req.method === 'POST'
        && req.url === '/frontend/login';
    }).flush({user_type: 'Test'});
    expect(userResponse).toEqual({user_type: 'Test'});

  });

有什么想法吗??

【问题讨论】:

    标签: angular unit-testing jasmine angular-test


    【解决方案1】:

    可能有两个原因:

    1. 您忘记在末尾添加done() 函数。

      it('should login', (done) => {
        const service: AuthenticationService = TestBed.get(AuthenticationService);
        const http = TestBed.get(HttpTestingController);
        let userResponse;
      
        service.Login('email', 'password').then((response) => {
          userResponse = response;
        });
      
        http.expectOne((req) => {
          return req.method === 'POST'
          && req.url === '/frontend/login';
        }).flush({user_type: 'Test'});
        expect(userResponse).toEqual({user_type: 'Test'});
        done(); // missed done function 
      });
      
    2. 您需要增加默认超时jasmine.DEFAULT_TIMEOUT_INTERVAL。 `

      它可以在任何给定的描述之外全局设置。

      jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
      

    【讨论】:

    • 我尝试将超时设置得更高,并将完成的函数调用设置到不同的位置,但这没关系。似乎永远无法到达 HTTP 调用。
    • 我很确定您需要将done() 函数放到另一个地方。在此处阅读有关异步测试的更多信息:jasmine.github.io/2.4/…