Mocking in unit tests serves several purposes:
- Control Dependencies: Unit tests should focus on testing specific units of code in isolation. By mocking dependencies, such as external API calls, databases, or services, you can control their behavior and ensure that the unit being tested is the sole focus. This helps in eliminating external factors that could interfere with the test results and isolates the unit under test.
- Increase Test Speed: Some dependencies may have slow response times or require specific setups before they can be tested. By mocking these dependencies, you can bypass the need for actual communication with external systems, leading to faster test execution. Mocking allows you to test more scenarios in a shorter amount of time, which is especially beneficial when running a large suite of tests.
- Reproduce Specific Scenarios: Mocking provides a way to simulate different scenarios or edge cases that may be difficult or time-consuming to reproduce in real-world situations. By creating mock responses or throwing specific errors, you can assess how the unit being tested handles different scenarios and ensure its robustness.
- Reduce Test Flakiness: Dependencies like external APIs or databases can introduce non-deterministic behaviors, such as network issues or data inconsistencies. By mocking these dependencies, you eliminate their unpredictability and make your tests more deterministic and reliable. This reduces the chances of false positives or false negatives in your test results.
- Isolate Faults: If a test fails, mocking can help you narrow down the cause to the specific unit being tested or its direct dependencies. By mocking, you can identify whether the issue lies within the unit itself or in its interactions with external components. This simplifies the debugging process and allows for more targeted fixes.
Overall, mocking during unit tests provides greater control, speed, reproducibility, reliability, and fault isolation, enabling you to thoroughly test individual units of code in an efficient and focused manner.
Example of mocking with a successful response
import axios from "axios";
jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios="">;
const mockGet = jest.fn();
mockGet.mockImplementation(() => {
const myResponse = {
status: 200,
data: {
data: [{ id: 1 }, { id: 2 }],
},
};
return Promise.resolve(myResponse);
});
mockedAxios.get.mockImplementation(mockGet);
</typeof>
Example of mocking with an error response
import axios from "axios";
jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios="">;
const mockGet = jest.fn();
mockGet.mockImplementation(() => {
const error = {
response: {
status: 404,
},
};
return Promise.reject(error);
});
mockedAxios.get.mockImplementation(mockGet);
</typeof>