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