问题
Got this error after upgrading to React when I ran my Jest unit tests:
React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers.
How do I fix it?
I'm using Jest 18.1.0.
回答1:
Found a workaround!
Steps:
- Create the file
__mocks__/react.js
- Add the following into
__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;
- Run jest !
As marked on comments on the code
This is the solution from https://github.com/facebook/react/issues/9102#issuecomment-283873039
回答2:
this worked for me:
- Install
raf
npm install --saveDev raf
or yarn add -D raf
- Add the polyfill to your
setupFiles
in yourjest
config inpackage.json
like this:
'setupFiles': ['raf/polyfill']
Note: if you have other setup files in this array, you may want to put raf/polyfill
first.
回答3:
If you just need to polyfill it for tests, then you don't actually need the throttling.
Create a new file with this code:
global.requestAnimationFrame = function (cb) {
return setTimeout(cb, 0);
};
Add that file to the jest/setupFiles
array in your package.json.
回答4:
If you are using create-react-app, some of these solutions will not work well (or at all, in the case of setupFiles
). What does work well is creating a file at src/setupTests.js
and adding your mock in there:
global.requestAnimationFrame = (cb) => { cb(); };
You can also add other global mocks in there (e.g. localStorage
and navigator.serviceWorker
).
回答5:
Another working solution!
The idea is to load a simple shim before each spec, by using the setupFiles property in the jest config.
Create a file shim.js
file (preferably in your root dir) and have this code in it:
global.requestAnimationFrame = (callback) => {
setTimeout(callback, 0);
};
Next, you may be having redundant code that keep reappearing in all/most of your files - and you want to put them in a single file and have them run before each spec also, to do that:
Create a setup.js
file in the root dir too. A good piece of redundant code to D.R.Y is the react enzyme adapter configuration code. Paste it here
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
Now create the jest.config.js
file, to specify the paths of the two files
{
module.exports = {
"setupFiles": ["<rootDir>shim.js", "<rootDir>setup.js"]
}
}
N.B: The jest config file take json
, so make sure json's in. Also, if your shim.js
and setup.js
files are not in the same dir as your jest.config.js
, adjust the path accordingly.
Hope this helps!
Credit: https://github.com/facebook/jest/issues/4545
回答6:
Here's a realistic way to mock 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;
}
});
});
in your test, it repeatedly calls the RAF callback until it reaches the max elapsed time that you set. It happens instantly, so you don't need to stall it.
回答7:
Just upgrade your react-scripts
to 1.0.15 or above. It has been officially fixed after that version. See more details in https://github.com/facebook/create-react-app/issues/3199
Search the comment of gaearon commented on 31 Oct 2017
回答8:
Turns out it was because I upgraded enzyme
without upgrading react
and react-dom
.
React 15.5 brings about some deprecations that caused many dependent libraries to have to update too. Make sure you are updating react
, react-dom
and check the README of those dependent packages for new libraries you have to install. For instance, Enzyme 2.8.2 now requires react-addons-test-utils
as a dependency.
来源:https://stackoverflow.com/questions/43604058/requestanimationframe-polyfill-error-in-jest-tests