
- Jest Mastery
- Jest - Getting Started
- Jest - Core Concepts
- Jest - Mocking
- Jest - Advanced Testing
- Jest - React Testing
- Jest - Configuration
- Jest - Special Testing Scenarios
- Jest - Performance & Advanced Topics
- Jest - Integrations
- Jest - Best Practices
- Jest - Deployment and CI/CD
- Jest Resources
- Jest - Useful Resources
- Jest - Discussion
Jest - Mocking
In this chapter, we'll learn about mocking in Jest. Mocking lets you replace real functions, modules, or API calls with mock versions so you can test parts of your code independently.
Using mock makes your tests faster, more reliable, and lets you focus on the core logic while controlling external dependencies. Let's get started.
What is Mocking in Jest?
Mocking in Jest means replacing real functions, modules, or components with mock versions (fake versions that act like the real ones) to test how your code interacts with them. This helps you focus on testing specific parts of your code while avoiding the need to rely on external systems, making your tests faster and more reliable.
Mocking is especially helpful when:
- External services(like APIs or databases) are slow, unavailable, or not needed for the test.
- You want to focus on testing a specific part of your code without interference from other parts.
- You need to simulate errors or unusual situations(edge cases) that might be hard to reproduce with real data.
Why Mocking is Important in Jest?
Mocking is important because it:
- Isolates code: You can test specific parts of your code independently by replacing real dependencies with mock.
- Improves test: Mocking avoids calling actual functions or external systems, making tests run faster.
- Provides control: Mocking allows you to define how dependencies behave, such as returning specific values or causing errors.
- Simplifies testing edge cases: Mocking makes it easier to test rare situations, like errors or unexpected data from external services.
Types of Mocking in Jest
In Jest, there are different types of mocking you can use depending on what you need to test. Here are the main types of mocking available:
- Function Mocking
- Module Mocking
- Manual Mocks
- Mocking Timers
- Mocking Classes
- Mocking API Calls
- Spy Mocks
Jest - Function Mocking
Function mocking in Jest means creating fake versions of functions to use in tests. These mocks behave like real ones but allow you to control their actions, track calls, decide what they return, and test different situations without running the actual code.
Creating a Mock Function
You can create a mock function using jest.fn(). It behaves like the real function but lets you control its behavior, such as the return value.
// Mock returns 6 const mockFunction = jest.fn().mockReturnValue(6);
Tracking Calls
You can track how many times a mock function was called and what arguments it received.
const mockFunction = jest.fn(); mockFunction(1, 2); // Verifies mock was called with 1 and 2 expect(mockFunction).toHaveBeenCalledWith(1, 2);
Simulating Multiple Return Values
You can make a mock function return different values for different calls using mockReturnValueOnce().
const mockFunction = jest.fn() // First call returns 1 .mockReturnValueOnce(1) // Second call returns 2 .mockReturnValueOnce(2);
Custom Implementation
You can define custom behavior for your mock function using mockImplementation().
// Adds two numbers const mockFunction = jest.fn().mockImplementation((a, b) => a + b);
Resetting Mocks
After each test, you can reset the mock's state using mockReset(). This ensures that one test doesn't affect the next.
const mockFunction = jest.fn(); // Resets the mock's state mockFunction.mockReset();
Jest - Module Mocking
Sometimes, you may want to mock an entire module instead of just a function. This is useful when you want to test specific parts of your code without relying on the actual module implementation (e.g., an API or database).
How to Mock a Module?
To mock a module, you can use jest.mock(). This replaces the real module implementation with a mock version.
Example
// Assume we have a math.js module that contains an add function jest.mock('./math'); // Mock the math module import * as math from './math'; test('mock module example', () => { // Mock the add function to return 10 math.add.mockReturnValue(10); // The mock returns 10, not the real implementation expect(math.add(2, 3)).toBe(10); });
Jest - Manual Mocks
Manual mocks give you more control over Jest's mocking. You can create your own mock for a module, put it in a __mocks__ directory, and Jest will use your mock instead of the real module during tests.
How to Create Manual Mocks?
In Jest, you can create manual mocks by following these simple steps:
- Create a __mocks__ folder: Place it next to the module you want to mock.
- Define the mock behavior inside the __mocks__ folder.
Example
- Original module (math.js): This is the real implementation you want to mock.
// math.js export const add = (a, b) => a + b;
// __mocks__/math.js export const add = jest.fn(() => 42); // Always returns 42
jest.mock('./math'); // Mock the module expect(add()).toBe(42); // Test mock behavior
Jest Mocking Timers
Timer mocking in Jest allows you to control functions like setTimeout, setInterval, and clearTimeout during your tests. This is helpful when you want to test time-related behaviors without waiting for actual time delays.
How to Mock Timers?
To mock timers, use jest.useFakeTimers() to replace the real timers with fake ones, and control the passage of time with methods like jest.runAllTimers().
Example
test('mocking setTimeout with fake timers', () => { // Enable fake timers jest.useFakeTimers(); const mockCallback = jest.fn(); // Set a timeout with the mock callback setTimeout(mockCallback, 1000); // Move time forward and trigger all timers jest.runAllTimers(); // Verify that the mock callback was called expect(mockCallback).toHaveBeenCalled(); });
Jest - Mocking Classes
In Jest, you can mock class methods or entire classes, which is helpful when testing code that depends on classes. Mocking lets you replicate class behavior without running the actual code or causing any side effects.
How to Mock a Class?
To mock a class, you can use jest.fn() for individual methods or mock the entire class.
Example
// Define the Car class class Car { start() { return 'Car started'; } } // Mock the start method of the Car class test('mocking class methods', () => { // Mocking start method const mockStart = jest.fn().mockReturnValue('Mocked start'); const car = new Car(); // Replace the start method with the mock car.start = mockStart; // Verify the mock behavior expect(car.start()).toBe('Mocked start'); });
Jest - Mocking API Calls
Mocking API calls in Jest means creating fake responses for API requests instead of actually connecting to a real API. This helps make your tests faster and more reliable because you don't need to depend on real external services or the internet to run them.
How to Mock API Calls?
You can mock libraries like axios or fetch to pretend as if the server is responding, without actually making a request to a real server.
Example
// This mocks the axios library to prevent actual API calls jest.mock('axios'); import axios from 'axios'; test('mocking API call', async () => { // Mock the response of axios.get() axios.get.mockResolvedValue({ data: { user: 'John' } }); // Call the API function (same as real code) const response = await axios.get('/user'); // Check if the mock response is returned expect(response.data.user).toBe('John'); });
Jest - Spy Mocks
Spy mocks track how existing functions or methods are called without changing their behavior. You can use jest.spyOn() to watch a method on an object and then check how it was used in your tests.
How to Use Spy Mocks?
You can use jest.spyOn() to observe how a function or method was called.
Example
// Creating a car object with a startEngine method const car = { startEngine: () => { return 'Engine started'; }, }; test('spying on startEngine method', () => { // Spy on the startEngine method const spy = jest.spyOn(car, 'startEngine'); car.startEngine(); // Call the method // Check if startEngine was called expect(spy).toHaveBeenCalled(); spy.mockRestore(); // Restore the original method });