Cog
Cog

Reputation: 1705

How to mock a third party React component using Jest?

TLDR; what's the proper way to mock a React component imported from a third-party library?

I'm testing a component called <App/>. It consumes a 3rd part component called <Localize/> provided by a library called localize-toolkit.

I'm having some trouble mocking <Localize/> using Jest.

Here is how I've tried mocking it.

jest.mock('localize-toolkit', () => ({
  // Normally you pass in a key that represents the translated caption.
  // For the sake of testing, I just want to return the key.
  Localize: () => (key:string) => (<span>{key}</span>)
}));

And I've written a unit test for <App/> that looks like this.

it('Test', () => {
    const component = render(<App/>);
    expect(component).toMatchSnapshot();
  }
)

It will pass, however this is the warning message returned.

Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render.

And when I look at the snapshot, I get a series of periods "..." where the localized caption should appear.

Am I not mocking the Localize component properly?

Upvotes: 11

Views: 14215

Answers (2)

Cog
Cog

Reputation: 1705

Here's how I ended up doing it.

Note how the third-party component Localize needs to be returned as a function.

jest.mock('localize-toolkit', () => ({
  Localize: ({t}) => (<>{t}</>)
}));

and in case there are multiple components, and you only want to mock one of them, you can do this:

jest.mock("localize-toolkit", () => {
    const lib = jest.requireActual("localize-toolkit");

    return {
        ...lib,
        Localize: ({t}) => (<>{t}</>), 
    };
});

Upvotes: 17

smsivaprakaash
smsivaprakaash

Reputation: 1720

We can mock the 3rd party library for example in my case i need to mock react-lazyload

Component.tsx

import LazyLoad from 'react-lazyload';

render() {
  <LazyLoad><img/></LazyLoad>
}

In jest.config.js

module.exports = {
  moduleNameMapper: {
   'react-lazyload': '/jest/__mocks__/react-lazyload.js',
  }
}

In jest/mocks/react-lazyload.js

import * as React from 'react';

jest.genMockFromModule('react-lazyload');

const LazyLoad = ({children}) => <>{children}</>;

module.exports = { default: LazyLoad };

Upvotes: 2

Related Questions