Using Jest to mock a React component with props

Mike Hopkins picture Mike Hopkins · Jun 7, 2017 · Viewed 49.4k times · Source

I have a React component which contains some other components that depend on access to a Redux store etc., which cause issues when doing a full Enzyme mount. Let's say a structure like this:

import ComponentToMock from './ComponentToMock';

<ComponentToTest>
  ...some stuff
  <ComponentToMock testProp="This throws a warning" />
</ComponentToTest>

I want to use Jest's .mock() method to mock out the sub-component, so that it is not a concern for the test.

I'm aware that I can mock out a straight component with something like:

jest.mock('./ComponentToMock', () => 'ComponentToMock');

However, as this component would normally receive props, React gets upset, giving a warning about unknown props (in this case, testProp) being passed to <ComponentToMock />.

I've tried to return a function instead, however you can't return JSX (from what I could tell) in a Jest mock, due to it being hoisted. It throws an error in this case.

So my question is how can I either

a) get ComponentToMock to ignore props passed to it, or

b) return a React component that can be used to mock the child component that I'm not worried about testing.

Or... is there a better way?

Answer

Mike Reifman picture Mike Reifman · Jul 20, 2017

There's a note at the bottom of the docs for jest.mock() for preventing the hoisting behavior:

Note: When using babel-jest, calls to mock will automatically be hoisted to the top of the code block. Use doMock if you want to explicitly avoid this behavior.

Then you can do as you described: return a function that is a stub of the component you don't need to test.

jest.doMock('./ComponentToMock', () => {
  const ComponentToMock = () => <div />;
  return ComponentToMock;
});

const ComponentToTest = require('./ComponentToTest').default;

It's helpful to name the stub component since it gets rendered in snapshots.