首页 > 解决方案 > 在 HTTP 请求中测试 RxJS 映射函数

问题描述

我正在测试一个包含私有映射器方法的 Angular 服务,如下所示,我的目标是在 RxJS 映射中模拟该方法,因为它似乎没有经过覆盖测试。

在此处输入图像描述

这是我的 Jest 测试,但该方法似乎没有经过测试,也许我需要模拟私有方法?

 test('should test the download file', () => {
    const fakeurl = 'http://fakeurl';
    service.downloadFile(fakeurl).subscribe((resp: IDownload) => {
      expect(resp).toBe(mockDownloadedFile);
    });

    const req = httpMock.expectOne(request => request.url.includes(fakeurl), 'call api');
    expect(req.request.method).toBe('GET');
    req.flush(new Blob());
  });

标签: angulartypescriptjestjs

解决方案


我在想,因为delay你的断言在你subscribe永远不会运行。

试试这个以确保订阅内部的断言正在运行

test('should test the download file', () => {
    const fakeurl = 'http://fakeurl';
    service.downloadFile(fakeurl).subscribe((resp: IDownload) => {
      expect(1).toBe(2); // this test should fail
      expect(resp).toBe(mockDownloadedFile);
    });

    const req = httpMock.expectOne(request => request.url.includes(fakeurl), 'call api');
    expect(req.request.method).toBe('GET');
    req.flush(new Blob());

    subscripton.unsubscribe(); // unusbscribe from previous subscription
  });

确保上述测试未能确保它实际上进入了断言的订阅块内部。如果它通过了,你就知道它没有进入订阅块。

对于您的情况,我会利用fakeAsync虚假的方式提前时间:

import { fakeAsync, tick } from "@angular/core/testing";
....
test('should test the download file', fakeAsync(() => { // add fakeAsync here
  const fakeurl = 'http://fakeurl';
  let response: IDownload;
  const subscription = service.downloadFile(fakeurl).subscribe((resp: IDownload) => {
    expect(1).toBe(2); // ensure this fails and remove it once you see it failing
    response = resp; // assign response here
  });

  const req = httpMock.expectOne(request => request.url.includes(fakeurl), 'call api');
  expect(req.request.method).toBe('GET');
  req.flush(new Blob());
  tick(3500); // advance the timer by 3500ms so it gets passed the delay
  expect(response).toBe(mockDownloadedFile);
}));

现在我想既然你在使用jest,你会遇到使用问题fakeAsync。也许将其更改test为 an it,看看这是否对您有用。


推荐阅读