How to mock react component and check if called with props

Viewed 988

In another project that uses jest 26 I could do the following:

import ChildComponent from './ChildComponent';
jest.mock('./ChildComponent', () => jest.fn(() => 'ChildComponent'));

const { container, debug } = render(<ParentComponent />);
expect(ChildComponent).lastCalledWith({a, b, c});

debug() // returns `<body><div>ChildComponent</div></body>`

Now in my current project that runs jest 27 I can't mock ChildComponent like that, I need to remove jest.fn for it to work: jest.mock('./ChildComponent', () => () => 'ChildComponent'); fine, I can live with that...

But, now when I expect child to be called with abc it says: Matcher error: received value must be a mock or spy function

I can't find anything in the changelog of jest 27, has anyone run into this issue? How can I mock a react component to return a string PLUS check if called with props??

2 Answers

::Answering my own question::

My issue was because react-scripts had set resetMocks to true so the mock was being reset before the test.

I had tried to change it in jest.config.js but it was also not working.

Adding resetMocks: false to package.json solved the issue for me.

There are other ways to do (without resetMocks):

Number One

// You can mock the component to render nothing, but can test the props received
jest.mock('./ChildComponent', () => jest.fn(() => null));

Number Two

// You can mock the component to render a simple div with the props received
// This will show a <div> with props on debug()
jest.mock('./ChildComponent', () =>
  jest.fn(props => <div {...props} />),
);

And to test it:

render(<ParentComponent />);

// You have to set a second arg with {} to test work and get the received props
expect(ChildComponent).toHaveBeenCalledWith({a, b, c}, {});
Related