Jest URL.createObjectURL is not a function

JavascriptReactjsTestingBlobJestjs

Javascript Problem Overview


I'm developping a reactJs application. I'm using jest to test my application. I want to test a function that download a blob.

But unfortunately I receve this error: > URL.createObjectURL is not a function

my test function:

describe('download', () => {
    const documentIntial = { content: 'aaa' };
    it('msSaveOrOpenBlob should not have been called when navigao is undefined', () => {
      window.navigator.msSaveOrOpenBlob = null;
      download(documentIntial);
      expect(window.navigator.msSaveOrOpenBlob).toHaveBeenCalledTimes(0);
    });
  });

The function I want to test:

export const download = document => {
  const blob = new Blob([base64ToArrayBuffer(document.content)], {
    type: 'application/pdf',
  });
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob);
    return;
  }

  const fileURL = URL.createObjectURL(blob);
  window.open(fileURL);
};

Javascript Solutions


Solution 1 - Javascript

This would appear to be as simple as setting up URL on the Global in Jest. Something like

describe('download', () => {
  const documentIntial = { content: 'aaa' };
  global.URL.createObjectURL = jest.fn();
  it('msSaveOrOpenBlob should not have been called when navigao is undefined', () => {
    global.URL.createObjectURL = jest.fn(() => 'details');
window.navigator.msSaveOrOpenBlob = jest.fn(() => 'details');
download(documentIntial);
expect(window.navigator.msSaveOrOpenBlob).toHaveBeenCalledTimes(1);
  });
});

This should result in a test that you can also use for checking if global.URL.createObjectURL was called. As a side note: you may also run into a similar issue with window.open I would suggest mocking that as well if this becomes the case.

Solution 2 - Javascript

jsdom, the JavaScript implementation of the WHATWG DOM used by jest doesn't implement this method yet.

You can find an open ticket about this exact issue on their github page where some workarounds are provided in comments. But if you need the blobURL to actually work you'll have to wait this FR is solved.

Workaround proposed in the comments of the issue for jest:

function noOp () { }
if (typeof window.URL.createObjectURL === 'undefined') { 
  Object.defineProperty(window.URL, 'createObjectURL', { value: noOp})
}

Solution 3 - Javascript

Since window.URL.createObjectURL is not (yet) available in jest-dom, you need to provide a mock implementation for it.

Don't forget to reset the mock implementation after each test.

describe("your test suite", () => {
  window.URL.createObjectURL = jest.fn();

  afterEach(() => {
    window.URL.createObjectURL.mockReset();
  });

  it("your test case", () => {
    expect(true).toBeTruthy();
  });
});

Solution 4 - Javascript

> You just have to Write this in your setupTest.js

window.URL.createObjectURL = function() {};

Solution 5 - Javascript

Just mocking the function global.URL.createObjectURL did not work for me, because the function was used by some modules during import and I got the error Jest URL.createObjectURL is not a function during import.

Instead it did help to create a file mockJsdom.js

Object.defineProperty(URL, 'createObjectURL', {
  writable: true,
  value: jest.fn()
})

Then import this file as the first import in your file containing the test

import './mockJsdom'
import { MyObjects} from '../../src/lib/mylib'

test('my test', () => {
  // test code
}

Found here: https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom

Solution 6 - Javascript

The package jsdom-worker happens to provide this method, as well as adding support for web workers. The following worked for me:

npm install -D jsdom-worker

Then in package.json, edit or add a jest key:

{
  ...
  "jest": {
    "setupFiles": [
      "jsdom-worker"
    ]
  }
}

Solution 7 - Javascript

use webkitURL.createObjectURL instead of URL.createObjectURL its work for me

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMelchiaView Question on Stackoverflow
Solution 1 - JavascriptNone of your Beez WaxView Answer on Stackoverflow
Solution 2 - JavascriptKaiidoView Answer on Stackoverflow
Solution 3 - JavascriptjackdbdView Answer on Stackoverflow
Solution 4 - JavascriptVarun PradhanView Answer on Stackoverflow
Solution 5 - JavascriptMichael SView Answer on Stackoverflow
Solution 6 - JavascriptLucas WimanView Answer on Stackoverflow
Solution 7 - JavascriptdwalvesView Answer on Stackoverflow