Home > OS >  Expectation fails, when testing code in javascript fetch.then block
Expectation fails, when testing code in javascript fetch.then block

Time:03-09

I try to verify that window.open() is called within a then block. Here is a minimal example.

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

function openWindow() {
  const linksource = `data:application/pdf;base64,somePDF`;
  fetch(linksource).then(() => {
    window.open();
  });
}

describe('Asynchronus Testing', () => {
  it('opens a window', fakeAsync(() => {
    // Dont actually open a window
    window.open = () => window;
    spyOn(window, 'open');

    openWindow();
    tick();

    expect(window.open).toHaveBeenCalled();
  }));
});

window.open() is actually called, but the expectation fails:

Error: Expected spy open to have been called.

The tick() is not helping even if I give it more time. I guess it is specific to fetch because the Promise.resolve().then() block works.

CodePudding user response:

I have noticed the same thing with fakeAsync/tick where the tick does not control some promises.

I would spy on fetch and make it return a random promise.

describe('Asynchronus Testing', () => {
  it('opens a window', fakeAsync(() => {
    // Dont actually open a window
    window.open = () => window;
    spyOn(window, 'open');
    // !! spy on window fetch and return a random promise
    spyOn(window, 'fetch').and.returnValue(Promise.resolve({}));

    openWindow();
    tick();

    expect(window.open).toHaveBeenCalled();
  }));
});

It should hopefully work with that modification. You should also not be making Http calls in a unit test (general rule).

  • Related