2

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:

  • Use Enzyme's 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).
  • Use Enzyme's 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.
  • Just use Enzyme's 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)

Brian Le
  • 2,646
  • 18
  • 28
  • Did you solve this problem? – Tim MG May 20 '19 at 11:47
  • @TimMG i decided to extract the part inside react-spring to a different component and test it. However i dont think we need to do this with the introduction of hooks – Brian Le May 20 '19 at 12:22
  • I followed your instructions and made a new component for the animation part, but my test still fails. This is probably because the new component is imported in the component I'm trying to test. – Tim MG May 20 '19 at 13:18
  • @TimMG If u open a new question, I will be more than happy to answer it – Brian Le May 20 '19 at 13:19
  • Take a look at https://stackoverflow.com/questions/56220746/how-to-test-a-react-component-which-uses-react-spring – Tim MG May 20 '19 at 13:27

1 Answers1

2

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.)

leenull
  • 36
  • 3
  • Sounds like a good approach. Have you tried the new hook api? – Brian Le Jun 05 '19 at 14:19
  • I haven't yet, but I will. I guess they can be mocked in a similar manner. Something like `export const useSpring = () => [{}, () => {}];` – leenull Jun 06 '19 at 08:08