Mastering Jest: Day 4 — Mocking Functions and Modules

Mastering Jest: Day 4 — Mocking Functions and Modules

Introduction

Photo by Lavi Perchik on Unsplash

Welcome to Day 4 of our Jest journey! Yesterday, we explored testing asynchronous code. Today, we’ll delve into mocking functions and modules, a crucial aspect of unit testing that ensures your tests are isolated and reliable.

Why Mocking Matters

In real-world applications, functions often depend on external services, modules, or functions. Mocking allows you to replace these dependencies with controlled substitutes, ensuring your tests are fast and deterministic.

Mocking Functions with Jest

Jest provides powerful tools to mock functions. Here’s a simple example:

// user.js
const fetchData = require('./fetchData');

async function getUserData(userId) {
const data = await fetchData(userId);
return data.user;
}

module.exports = getUserData;

To test getUserData, we need to mock fetchData:

// user.test.js
const getUserData = require('./user');
const fetchData = require('./fetchData');

jest.mock('./fetchData'); // Mock the fetchData module

test('returns user data', async () => {
fetchData.mockResolvedValue({ user: 'John Doe' });

const user = await getUserData(1);
expect(user).toBe('John Doe');
});

In this test, we mock fetchData to return a specific value, ensuring getUserData works correctly without making actual API calls.

Mocking Modules

Sometimes, you need to mock an entire module. Jest makes this easy with jest.mock:

// api.js
const axios = require('axios');

async function getUser(userId) {
const response = await axios.get(`/users/${userId}`);
return response.data;
}

module.exports = getUser;

To mock axios in your tests:

// api.test.js
const getUser = require('./api');
const axios = require('axios');

jest.mock('axios');

test('fetches user data', async () => {
const user = { name: 'Jane Doe' };
axios.get.mockResolvedValue({ data: user });

const result = await getUser(1);
expect(result).toEqual(user);
});

Here, we mock axios.get to return a specific response, isolating the test from the actual axios module.

Mock Implementations

You can also provide custom implementations for mocked functions:

// math.js
function add(a, b) {
return a + b;
}

module.exports = add;

Mocking add with a custom implementation:

// math.test.js
const add = require('./math');

jest.mock('./math', () => jest.fn((a, b) => a * b));

test('adds numbers using mock implementation', () => {
expect(add(2, 3)).toBe(6); // Mocked implementation multiplies instead of adding
});

This flexibility allows you to tailor the behavior of mocks to suit your testing needs.

Conclusion

Mocking is an essential technique in unit testing, ensuring your tests are isolated, reliable, and fast. By mastering Jest’s mocking capabilities, you can confidently test functions and modules in isolation from their dependencies.

Stay tuned for Day 5, where we’ll explore snapshot testing with Jest. Feel free to share your experiences and any questions you have in the comments below!