1

I am testing an Angular service that includes a private mapper method as you can see below, my goal is to mock the method inside the RxJS map because it seems not to be tested for the coverage.

enter image description here

This is my Jest test but the method seems not tested, maybe I need to mock the private method?

 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());
  });
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Gelso77
  • 1,763
  • 6
  • 30
  • 47

1 Answers1

0

I am thinking because of the delay, your assertion inside of your subscribe never runs.

Try this to ensure that the assertions inside of the subscribe are running

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
  });

Ensure the above test fails to ensure that it is actually going inside of the subscribe block for assertions. If it passes, you know it is not going inside of the subscribe block.

For your case, I would take advantage of fakeAsync to advance time in a fake way:

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);
}));

Now I think since you're using jest, you will have an issue of using fakeAsync. Maybe change the test to an it and see if that will work for you.

AliF50
  • 16,947
  • 1
  • 21
  • 37
  • Note that `test` and `it` are aliases for exactly the same thing: https://jestjs.io/docs/api#testname-fn-timeout – jonrsharpe Apr 09 '21 at 16:48
  • Ok, nevermind, I think I didn't read this question properly (https://stackoverflow.com/questions/56529330/using-angular-testing-fakeasync-with-jest-it-each). I think either `test` or `it` should work. – AliF50 Apr 09 '21 at 16:51