Jest 测试中的 `requestAnimationFrame` polyfill 错误
`requestAnimationFrame` polyfill error in Jest tests
当我 运行 我的 Jest 单元测试时升级到 React 后出现此错误:
React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers.
我该如何解决?
我正在使用 Jest 18.1.0。
原来是因为我升级了enzyme
而没有升级react
和react-dom
.
React 15.5 带来了一些弃用,导致许多依赖库也必须更新。确保您正在更新 react
、react-dom
并检查这些依赖包的自述文件以了解您必须安装的新库。例如,Enzyme 2.8.2 现在需要 react-addons-test-utils
作为依赖项。
找到解决方法!
步骤:
- 创建文件
__mocks__/react.js
- 将以下内容添加到
__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;
- 运行开玩笑!
如代码注释中所标记
这是来自
https://github.com/facebook/react/issues/9102#issuecomment-283873039
如果你只需要为测试填充它,那么你实际上不需要节流。
使用此代码创建一个新文件:
global.requestAnimationFrame = function (cb) {
return setTimeout(cb, 0);
};
将该文件添加到 package.json 中的 jest/setupFiles
数组。
这对我有用:
- 安装
raf
npm install --saveDev raf
或 yarn add -D raf
- 将 polyfill 添加到
package.json
中 jest
配置中的 setupFiles
,如下所示:
'setupFiles': ['raf/polyfill']
注意:如果您在此数组中还有其他安装文件,您可能希望将 raf/polyfill
放在第一位。
如果您使用的是 create-react-app,其中一些解决方案将无法正常工作(或者根本无法正常工作,在 setupFiles
的情况下)。行之有效的方法是在 src/setupTests.js
处创建一个文件并在其中添加您的模拟:
global.requestAnimationFrame = (cb) => { cb(); };
您还可以在其中添加其他全局模拟(例如 localStorage
和 navigator.serviceWorker
)。
另一个可行的解决方案!
想法是在每个规范之前加载一个简单的垫片,通过使用 jest 配置中的 setupFiles 属性。
创建文件 shim.js
文件(最好在您的根目录中)并在其中包含以下代码:
global.requestAnimationFrame = (callback) => {
setTimeout(callback, 0);
};
接下来,您的文件 all/most 中可能会出现重复出现的冗余代码 - 您希望将它们放在一个文件中并在每个规范之前也有它们 运行,以这样做:
也在根目录中创建一个 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: jest 配置文件占用 json
,所以确保 json在里面。此外,如果您的 shim.js
和 setup.js
文件与您的 jest.config.js
不在同一目录中,请相应地调整路径。
希望对您有所帮助!
只需将您的 react-scripts
升级到 1.0.15 或更高版本。在该版本之后已正式修复。在 https://github.com/facebook/create-react-app/issues/3199
中查看更多详细信息
搜索gaearon commented on 31 Oct 2017
的评论
这是模拟 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 回调,直到达到您设置的最大运行时间。它立即发生,所以你不需要拖延它。
如果你使用 TypeScript,最好的解决方案是;
window.requestAnimationFrame = (): number => {
window.clearTimeout();
return 0;
};
在你所有的描述和测试之前。
当我 运行 我的 Jest 单元测试时升级到 React 后出现此错误:
React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers.
我该如何解决?
我正在使用 Jest 18.1.0。
原来是因为我升级了enzyme
而没有升级react
和react-dom
.
React 15.5 带来了一些弃用,导致许多依赖库也必须更新。确保您正在更新 react
、react-dom
并检查这些依赖包的自述文件以了解您必须安装的新库。例如,Enzyme 2.8.2 现在需要 react-addons-test-utils
作为依赖项。
找到解决方法!
步骤:
- 创建文件
__mocks__/react.js
- 将以下内容添加到
__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;
- 运行开玩笑!
如代码注释中所标记
这是来自 https://github.com/facebook/react/issues/9102#issuecomment-283873039
如果你只需要为测试填充它,那么你实际上不需要节流。
使用此代码创建一个新文件:
global.requestAnimationFrame = function (cb) {
return setTimeout(cb, 0);
};
将该文件添加到 package.json 中的 jest/setupFiles
数组。
这对我有用:
- 安装
raf
npm install --saveDev raf
或 yarn add -D raf
- 将 polyfill 添加到
package.json
中jest
配置中的setupFiles
,如下所示:
'setupFiles': ['raf/polyfill']
注意:如果您在此数组中还有其他安装文件,您可能希望将 raf/polyfill
放在第一位。
如果您使用的是 create-react-app,其中一些解决方案将无法正常工作(或者根本无法正常工作,在 setupFiles
的情况下)。行之有效的方法是在 src/setupTests.js
处创建一个文件并在其中添加您的模拟:
global.requestAnimationFrame = (cb) => { cb(); };
您还可以在其中添加其他全局模拟(例如 localStorage
和 navigator.serviceWorker
)。
另一个可行的解决方案!
想法是在每个规范之前加载一个简单的垫片,通过使用 jest 配置中的 setupFiles 属性。
创建文件 shim.js
文件(最好在您的根目录中)并在其中包含以下代码:
global.requestAnimationFrame = (callback) => {
setTimeout(callback, 0);
};
接下来,您的文件 all/most 中可能会出现重复出现的冗余代码 - 您希望将它们放在一个文件中并在每个规范之前也有它们 运行,以这样做:
也在根目录中创建一个 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: jest 配置文件占用 json
,所以确保 json在里面。此外,如果您的 shim.js
和 setup.js
文件与您的 jest.config.js
不在同一目录中,请相应地调整路径。
希望对您有所帮助!
只需将您的 react-scripts
升级到 1.0.15 或更高版本。在该版本之后已正式修复。在 https://github.com/facebook/create-react-app/issues/3199
搜索gaearon commented on 31 Oct 2017
这是模拟 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 回调,直到达到您设置的最大运行时间。它立即发生,所以你不需要拖延它。
如果你使用 TypeScript,最好的解决方案是;
window.requestAnimationFrame = (): number => {
window.clearTimeout();
return 0;
};
在你所有的描述和测试之前。