I am trying to snapshot test my React components with Jest and Enzyme. Some components have the animation component (imported from react-spring/react-motion
) in them, which renders a function as its child. This makes testing incredibly hard. I did quite a bit of research and came up with 3 ideas:
mount
to render everything, and snapshot test it. I found it impossible/ineffective for expensive components, and the snapshots produced are often really heavy (1MB - 2MB).shallow
and snapshot test the component. Then find the animation component, render the children inside it using Enzyme's renderProp()
and snapshot test them. This worked great until I found that renderProp()
doesn't work nicely with <StaggeredMotion />
for react-motion
and react-spring
. A workaround for this issue is explicitly call the function as .prop('children')()
, then shallow the whole thing, but the code will then look messy and tough to read.shallow
and snapshot test the component. The rest are on the library's side. The question is: Which one should I use? If none of these are good enough, what are the alternatives? Thanks in advance.
(If you need a code sample, I am more than happy to provide)
I got around the problems with testing components that use react-spring by mocking react-spring for Jest.
To do so, add this to your Jest config:
[...]
"moduleNameMapper": {
"^react-spring(.*)$": "<rootDir>/jest/react-spring-mock.js"
},
The file /jest/react-spring-mock.js
can look like this:
const React = require('react');
function renderPropsComponent(children) {
return React.createElement('div', null, children()({}));
}
export function Spring(props) {
return renderPropsComponent(props.children);
};
export function Trail(props) {
return renderPropsComponent(props.children);
};
export function Transition(props) {
return renderPropsComponent(props.children);
};
export function Keyframes(props) {
return renderPropsComponent(props.children);
};
export function Parallax(props) {
return renderPropsComponent(props.children);
};
export const animated = {
div: (props) => {
return React.createElement('div', null, props.children)
},
};
Note: these mocks are focused on the render-props API of react-spring.
Also, this technique will results in ignoring everything that is normally generated by react-spring in your tests. (It will create a container <div>
instead.)