Jest URL.createObjectURL 不是函数

问题描述 投票:0回答:8

我正在开发一个reactJs应用程序。我正在使用 jest 来测试我的应用程序。 我想测试一个下载 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);
    });
  });

我要测试的功能:

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 reactjs testing blob jestjs
8个回答
84
投票

这看起来就像在 Jest 中的 Global 上设置

URL
一样简单。类似的东西

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

这应该会产生一个测试,您也可以使用该测试来检查是否调用了

global.URL.createObjectURL
。附带说明:您也可能会遇到类似的问题
window.open
如果出现这种情况,我建议也嘲笑这一点。


32
投票

由于

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

19
投票

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

您可以在他们的 github 页面上找到关于此确切问题的公开票证,其中评论中提供了一些解决方法。但如果您需要 blobURL 实际工作,您将不得不等待此 FR 解决。

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

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

19
投票

您只需将其写入 setupTest.js

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

7
投票

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

npm install -D jsdom-worker

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

jest
键:

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

6
投票

只是嘲笑该函数

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

相反,它确实有助于创建文件

mockJsdom.js

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

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

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

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

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


0
投票

将反应测试库与笑话一起使用:

我必须在测试中添加

jest.spyOn(URL, 'createObjectURL').mockImplementation();
。 这与为 dom 对象创建模拟文件一起工作

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

并添加该模拟文件的导入语句作为我的测试文件中的第一个导入。

注意:模拟文件不能位于tests目录中


0
投票

我刚刚解决了这个问题,用这段代码,只是为了知道整个循环运行良好,模拟一个 blob => global.URL.createObjectURL = jest.fn( (斑点:任意)=>

blob:${blob.size}#t=${Date.now()}
)

© www.soinside.com 2019 - 2024. All rights reserved.