Mocking React components and modules is something I find myself doing often in Jest. I’m instinctively weary of mocks, test doubles can create a false sense of security if misused, but they are incredibly important when dealing with third party libraries and "Inner-Source" packages, whilst avoiding the indirection and complexity of other techniques such as Dependency Injection. I don’t personally believe that mocking/patching in anyway compromises a clean architecture.
Below is a common mock in the codebase I'm working on. Next.js links will fail with an TypeError without a RouterContext. Either we add the router or mock the component, the latter seems easiest and prevents the test from knowing too much about what's needed underneath.
jest.mock('next/link', () => ({ children }: { children: JSX.Element }) => children);
Of course that'll work on any component import.
Unfortunately if you want to return some JSX in the mock the react/display-name ESlint rule will kick in. We can ignore the rule or perhaps define the mock like this:
jest.mock('../module', () => function Named() { return <div />; });
Oh, and named exports? The above examples show default exports. The example below takes Stripe's CardElement and return a no-op component.
jest.mock('@stripe/react-stripe-js', () => ({ CardElement: () => null }));
Top comments (0)