`requestAnimationFrame` polyfill 错误

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

在我运行 Jest 单元测试时升级到 React 后出现此错误:

React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers.

我该如何解决?

我正在使用 Jest 18.1.0.

reactjs jestjs react-dom
10个回答
36
投票

找到解决方法!

步骤:

  1. 创建文件
    __mocks__/react.js
    (见
    __mocks__
    文件夹在这里
  2. 将以下内容添加到
    __mocks__/react.js

const react = require('react');
// Resolution for requestAnimationFrame not supported in jest error :
// https://github.com/facebook/react/issues/9102#issuecomment-283873039
global.window = global;
window.addEventListener = () => {};
window.requestAnimationFrame = () => {
  throw new Error('requestAnimationFrame is not supported in Node');
};

module.exports = react;

  1. 开个玩笑!

如代码注释所示

这是解决方案 https://github.com/facebook/react/issues/9102#issuecomment-283873039


35
投票

这对我有用:

  1. 安装
    raf

npm install --saveDev raf
yarn add -D raf

  1. 将 polyfill 添加到你的
    setupFiles
    在你的
    jest
    配置中
    package.json
    像这样:

'setupFiles': ['raf/polyfill']

注意:如果您在此数组中还有其他设置文件,则可能需要先放置

raf/polyfill


9
投票

如果你只是需要为测试填充它,那么你实际上不需要节流。

使用此代码创建一个新文件:

global.requestAnimationFrame = function (cb) {
    return setTimeout(cb, 0);
};

将该文件添加到 package.json 中的

jest/setupFiles
数组中。


8
投票

如果您使用的是 create-react-app,其中一些解决方案将无法正常工作(或者根本无法正常工作,在

setupFiles
的情况下)。行之有效的是在
src/setupTests.js
创建一个文件并在其中添加您的模拟:

global.requestAnimationFrame = (cb) => { cb(); };

您还可以在其中添加其他全局模拟(例如

localStorage
navigator.serviceWorker
)。


1
投票

另一个可行的解决方案!

想法是在每个规范之前加载一个简单的垫片,通过使用 jest 配置中的 setupFiles 属性。

创建一个文件

shim.js
文件(最好在你的根目录中)并在其中包含以下代码:

global.requestAnimationFrame = (callback) => {
    setTimeout(callback, 0);
};

接下来,您可能会有重复出现在所有/大部分文件中的冗余代码 - 并且您想将它们放在一个文件中并让它们也在每个规范之前运行,以做到这一点:

也在根目录中创建一个

setup.js
文件。 D.R.Y 的一段很好的冗余代码是反应酶适配器配置代码。粘贴在这里

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

现在创建

jest.config.js
文件,指定两个文件的路径

{
    module.exports = {
        "setupFiles": ["<rootDir>shim.js", "<rootDir>setup.js"]
    }
}

N.B: 开玩笑的配置文件采用

json
,因此请确保 json 在其中。此外,如果您的
shim.js
setup.js
文件与您的
jest.config.js
不在同一目录中,请调整相应的路径。

希望这有帮助!

信用:https://github.com/facebook/jest/issues/4545


1
投票

这是模拟 requestAnimationFrame 的现实方法:

let time;
const maxTimeElapsed = 2000;

beforeEach(() => {
  time = 0;
  jest.spyOn(window, 'requestAnimationFrame').mockImplementation(cb => {
    time += 100;
    if (time < maxTimeElapsed) {
      return cb(time) as any;
    }
  });
});

在您的测试中,它会重复调用 RAF 回调,直到达到您设置的最大运行时间。它立即发生,所以你不需要拖延它。


0
投票

只需将您的

react-scripts
升级到1.0.15或更高版本。在该版本之后已正式修复。在 https://github.com/facebook/create-react-app/issues/3199 中查看更多详细信息

搜索

gaearon commented on 31 Oct 2017

的评论

0
投票

如果你使用 TypeScript,最好的解决方案是;

window.requestAnimationFrame = (): number => {
   window.clearTimeout();
   return 0;
};

在你所有的描述和测试之前。


0
投票

根据

raf
包文档此时需要运行
polyfill()
函数并指定需要填充的对象。在我的案例中有效:

require('raf').polyfill(global.window)

-1
投票

原来是因为我升级了

enzyme
而没有升级
react
react-dom
.

React 15.5 带来了一些弃用,导致许多依赖库也必须更新。确保您正在更新

react
react-dom
并检查这些依赖包的自述文件以了解您必须安装的新库。例如,Enzyme 2.8.2 现在需要
react-addons-test-utils
作为依赖项。

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