JavaScript > Testing and Debugging > Unit Testing > Using Jest
Jest Mocking Example
This snippet demonstrates how to use Jest's mocking capabilities to isolate a function from its dependencies during testing. It includes mocking a function, verifying that it was called, and checking the arguments it was called with.
The Function with Dependencies
This is a function that simulates fetching data from an API. It uses a setTimeout
to mimic the delay of a real API call. It accepts a callback function that will be called with the fetched data.
// api.js
export function fetchData(callback) {
setTimeout(() => {
const data = { message: 'Hello from API!' };
callback(data);
}, 1000);
}
The Function to Test
This function uses fetchData
to retrieve data and then processes it (in this case, converting the message to uppercase). We want to test that processData
calls fetchData
and correctly processes the data.
// dataProcessor.js
import { fetchData } from './api';
export function processData(callback) {
fetchData(data => {
const processedData = data.message.toUpperCase();
callback(processedData);
});
}
Setting up the Mock
This code mocks the fetchData
function using jest.mock
. This replaces the original fetchData
function with a mock function that we can control. The mock function simulates an API response with a message 'Mocked Data'. Inside the test, we call processData
and assert that the processed data is 'MOCKED DATA' and that fetchData
was called once. We also use done()
to handle the asynchronous nature of the test. This is important because fetchData
uses setTimeout
and Jest needs to know when the asynchronous operation is complete.
// dataProcessor.test.js
import { processData } from './dataProcessor';
import { fetchData } from './api';
jest.mock('./api', () => ({
fetchData: jest.fn(callback => {
callback({ message: 'Mocked Data' });
}),
}));
describe('processData', () => {
it('should call fetchData and process the data correctly', done => {
processData(processedData => {
expect(processedData).toBe('MOCKED DATA');
expect(fetchData).toHaveBeenCalledTimes(1);
done(); // Call done to signal the completion of the asynchronous test
});
});
});
Running the Test
As in the previous example, ensure you have Jest installed and configured in your project. Then, run the tests using the command:
npm test
Check your package.json
file and make sure you have a script defined:
"scripts": {
"test": "jest"
}
Concepts Behind the Snippet
This snippet demonstrates the concept of mocking, which is crucial for isolating units of code during testing. Mocking allows you to replace dependencies with controlled substitutes, enabling you to test code in a predictable environment without relying on external resources or complex setups. It allows you to focus on the logic within the unit of code you are testing.
Real-Life Use Case
In real-world applications, mocking is frequently used to test components that rely on external APIs, databases, or other services. For example, if you're testing a component that fetches data from a REST API, you can mock the API call to return a predefined response, avoiding the need to make actual network requests during testing.
Best Practices
toHaveBeenCalled
, toHaveBeenCalledWith
) to verify that your code interacts with the mocked dependencies as expected.jest.restoreAllMocks()
to ensure that you aren't leaking mocked functions across tests.
Interview Tip
Be prepared to explain the purpose of mocking, the different types of mocks (e.g., mock functions, mock modules), and how to use Jest's mocking API. Also, be ready to discuss scenarios where mocking is essential for effective unit testing.
When to Use Them
Use mocking when you need to isolate a unit of code from its dependencies. This is particularly useful when testing code that interacts with external APIs, databases, or other services.
Alternatives
Alternatives to Jest's mocking capabilities include Sinon.js, which provides a more comprehensive set of mocking and stubbing tools. However, Jest's built-in mocking is often sufficient for most use cases.
Pros
Cons
FAQ
-
What is mocking?
Mocking is the process of replacing a dependency with a controlled substitute (a mock) for testing purposes. -
Why is mocking important?
Mocking allows you to isolate units of code during testing, making tests more predictable and easier to write. It also allows you to test code that relies on external resources or services without actually interacting with those resources. -
How do I verify that a mock function was called?
You can use Jest'stoHaveBeenCalled
matcher to verify that a mock function was called. You can also usetoHaveBeenCalledWith
to check the arguments that the mock function was called with.