I want to mock a module for a test. Everything works, but I have to copy/paste the same code into every test file. How can I make this more maintainable?
(This is using Babel and TypeScript in a Next.js project.)
The production code looks like this:
import { useRouter } from 'next/router';
// Then call the hook in a React component:
const router = useRouter();
The test code:
// I need to access these mocks in the tests
const mockRouterPush = jest.fn();
const mockRouterBack = jest.fn();
jest.mock('next/router', () => ({
useRouter: () => ({
push: mockRouterPush,
query: { segment: 'seg1' },
back: mockRouterBack,
}),
}));
This works fine. The module and its hook are mocked for the test file, and I can refer to the mocks in the tests. The issue is that it's difficult to maintain across multiple test files.
Calls to jest.mock() are hoisted to the top of the file, and can only refer to variables that start with the word 'mock'.
With other mocks I've used require
within the module factory instead of import
; this works and reduces boilerplate, but (a) makes it more difficult for the tests to refer to the mocks and (b) my IDE (VSCode) won't auto-update require paths like it does with imports when I move files. For example:
jest.mock('react-i18next', () => {
// Sometimes the path is '../../../testhelpers' etc.
const { mockUseTranslation } = require('./testhelpers');
return {
useTranslation: mockUseTranslation,
};
});
I've tried doMock
and createMockFromModule
without success.
How do other folks deal with this issue?
Maybe using the __mocks__
directory can help you.
from the docs:
Manual mocks are defined by writing a module in a __mocks__/ subdirectory immediately adjacent to the module. For example, to mock a module called user in the models directory, create a file called user.js and put it in the models/__mocks__ directory.
You can also mock modules from the node_modules
directory.