DEV Community

Lucas jin
Lucas jin

Posted on

Mocking Modules in Jest: Three Powerful Techniques

Jest offers three effective methods to mock modules in your tests, enabling you to isolate and control external dependencies for focused testing. Here's a detailed breakdown of each approach:

  1. Direct Mocking in the Test File (Using jest.mock):
  • Ideal for mocking specific modules within the context of a single test file.

  • Syntax:

jest.mock('module-to-mock', () => ({
  // Mock implementation for the module
}));
Enter fullscreen mode Exit fullscreen mode

Example:

import { useSite } from 'src/context/SiteContext'; // Import the mocked module
jest.mock('src/context/SiteContext', () => ({
  useSite: jest.fn(),
}));
const useSiteMockImpelmetation = (market: string) => {
  (useSite as any).mockImplementation(() => {
    return {
      config: {
        market,
      },
    };
  });
};
 it('should show 4 list item if is spanish market', () => {
    mockMarket('es');
    renderComponent();
    const items = screen.getAllByRole('listitem');
    expect(items).toHaveLength(4);
  });
Enter fullscreen mode Exit fullscreen mode
  1. Global Mocking in jest.setup.ts:
  • Suitable for globally mocking modules across all test files.

  • Location: Create a file named jest.setup.ts (or .js) in your project's root directory.

Syntax:

jest.mock('module-to-mock', () => ({
  // Mock implementation for the module
}));
Example (in jest.setup.ts):



jest.mock('next-i18next', () => ({
  useTranslation: () => ({
    t: (key: string) => key,
  }),
}));
Enter fullscreen mode Exit fullscreen mode
  1. Manual Mocking in the __mocks__ Folder: (Manual Mocks · Jest )
  • Useful when the mocked module has complex logic or requires custom configuration.

  • Steps:

    • Create a directory named mocks within the same directory as the module you want to mock.
    • Inside __mocks__, create a file with the same name as the module (including extension). This file will contain your mock implementation.
  • Example (assuming src/context/SiteContext.tsx is the module to mock):

    • Create mocks/src/context/SiteContext.tsx.
    • Implement your mock logic in this file.
jest.mock('src/context/SiteContext', () => ({
  useSite: jest.fn(() => ({ 
    config: {
      market:'us'
      }
  })),
}));
Enter fullscreen mode Exit fullscreen mode

Then in the test file, we can use it:

jest.mock('src/context/SiteConfigContext');
Enter fullscreen mode Exit fullscreen mode
  • The useSite mock will automatically have the mock value that defined in the __mocks__/src/context/SiteContext.tsx file

Props and cons:

Method Pros Cons
Direct Mocking (jest.mock in Test File) Targeted: Mocks apply only to a specific test file. - Simple: Easy to set up for basic mocking needs. - Clear: Mock behavior stays within the test case. Limited Scope: Mocks are not shared across other tests. - Repetition: May lead to code duplication if mocking the same module in multiple tests.
Global Mocking (jest.setup.ts) Consistency: Mocks are applied consistently across all tests. - Convenience: No need to repeat mock definitions for each test. Global Impact: Accidental side effects in mocks can affect all tests. - Less Control: Less granular control over mock behavior compared to direct mocking.
Manual Mocking (mocks Folder) Flexibility: Suitable for complex mocking logic or custom configurations. - Organization: Keeps mock code separate for better maintainability. Setup: Requires creating a dedicated folder structure. - Potential Issues: May be harder to debug if mock logic becomes intricate.

Choosing the Right Method:

  • For basic mocks within a single test: Direct mocking with jest.mock is straightforward and keeps code focused.

  • For consistent global mocking: Use jest.setup.ts when you need the same mock behavior across all tests.

  • For complex or reusable mock logic: Manual mocking with the mocks folder offers flexibility and organization.

  • We always can use jest.mock('path') to unmock the mock file

Top comments (5)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.