开玩笑的URL.createObjectURL不是一个函数

Mel*_*hia 12 javascript testing blob reactjs jestjs

我正在开发一个reactJs应用程序。我正在开玩笑地测试我的应用程序。我想测试下载blob的功能。

但是不幸的是我收到这个错误:

URL.createObjectURL不是函数

我的测试功能:

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);
    });
  });
Run Code Online (Sandbox Code Playgroud)

我要测试的功能:

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);
};
Run Code Online (Sandbox Code Playgroud)

Moo*_*ure 15

这看起来就像URL在Jest中设置Global 一样简单。就像是

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

这将导致一个测试,您也可以使用该测试来检查是否global.URL.createObjectURL被调用。附带说明:您也可能会遇到类似的问题,window.open我建议您在这种情况下也要嘲笑。

  • 我有这个结果:expect(jest.fn())[.not].toHaveBeenCalledTimes() jest.fn() 值必须是一个模拟函数或间谍。收到:未定义 (2认同)

jac*_*dbd 11

由于window.URL.createObjectURL(尚未)在 jest-dom 中可用,您需要为它提供一个模拟实现。

不要忘记在每次测试后重置模拟实现。

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

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

  it("your test case", () => {
    expect(true).toBeTruthy();
  });
});
Run Code Online (Sandbox Code Playgroud)


Mic*_*l S 7

只是模拟该函数global.URL.createObjectURL对我来说不起作用,因为该函数在导入期间被某些模块使用,并且我在导入期间收到错误Jest URL.createObjectURL 不是函数

相反,它确实有助于创建一个文件mockJsdom.js

Object.defineProperty(URL, 'createObjectURL', {
  writable: true,
  value: jest.fn()
})
Run Code Online (Sandbox Code Playgroud)

然后将此文件作为包含测试的文件中的第一个导入导入

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

test('my test', () => {
  // test code
}
Run Code Online (Sandbox Code Playgroud)

在这里找到: https: //jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom


Rec*_*nic 7

jsdom-worker包恰好提供了这种方法,并添加了对 Web Worker 的支持。以下对我有用:

npm install -D jsdom-worker
Run Code Online (Sandbox Code Playgroud)

然后在 package.json 中,编辑或添加一个jest键:

{
  ...
  "jest": {
    "setupFiles": [
      "jsdom-worker"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)


Kai*_*ido 5

jsdom,jest使用的WHATWG DOM的JavaScript实现尚未实现此方法。

您可以在其github页面上找到有关此确切问题公开票证,其中在注释中提供了一些解决方法。但是,如果您需要blobURL实际工作,则必须等待此FR解决。

开玩笑的问题的评论中提出的解决方法:

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


Var*_*han 5

你只需要在你的 setupTest.js 中写这个

window.URL.createObjectURL = function() {};
Run Code Online (Sandbox Code Playgroud)

  • 当其他几个选项不起作用时,这最终对我有用。 (3认同)