Contents:

Course with employment: "Profession Test Engineer"
Learn moreMock testing can be compared to a car crash test, but instead of anthropomorphic dummies, it uses test doubles called mocks. In this article, we'll take a detailed look at what mocks are, how to create them, and when their use can lead to negative consequences. We will also conduct a mock test to practice writing our own software doubles.
- What is Mock Testing
- When to Use It
- Testing Tools
- Getting Ready
- Tests with Internal Dependencies
- Tests with External Dependencies
What is Mock Testing
Mock testing is a software testing technique in which real system components are replaced with test objects known as "doubles." These doubles can include fake databases, simulated mail servers, and other complex systems that allow tests to be run without having to interact with the real components. Test objects only simulate the functionality of real systems and do not contain actual logic or data, allowing developers to more effectively identify errors and verify the program's functionality in a controlled environment. This approach significantly speeds up the testing process and provides more flexible resource management.
There are two main types of test objects: mocks and stubs. Each of these types has its own subcategories. While this system may seem complex, we will examine each aspect in detail to clarify the differences and applications of mocks and stubs in software testing.
A mock is a test object used to simulate outbound dependencies in software. "Outbound" means that the application interacts with external systems to obtain or modify data. Using mock objects in testing allows developers to isolate functionality, verifying system behavior without having to access real external services. This speeds up the testing process and ensures higher reliability of results. Mocks are widely used in software development and testing, contributing to more effective error detection and improving code quality.
When developing an application for sending emails through a mail server, we can use a mock mail server. Instead of actually sending emails each time, a mock server accepts sending requests, records information about the intended emails, and returns mock confirmations of successful sending. This allows us, as developers, to effectively test code without having to interact with a real mail server. Using a mock server significantly simplifies the testing process and avoids the undesirable consequences associated with sending real emails.
Mock is a testing tool that provides a plausible implementation of the required functionality. It doesn't simply return predetermined values but also monitors code execution, ensuring its correctness. In addition, Mock provides call recordings, allowing developers to analyze and debug the testing process. This tool is especially useful when writing unit tests, as it helps simulate interactions with dependencies and control the behavior of the code under test. Using Mock improves the quality of testing and promotes more efficient software development.
A stub is a test object that simulates external influences, such as requests. For example, if we've developed a class to retrieve weather data from a third-party service, it's important to avoid sending real requests during testing. To achieve this, we can create a stub—a mock that will generate a request and return a preset temperature value. This allows us to effectively test our application without relying on the availability of an external service or wasting resources on real requests.
Mocks and stubs come in several varieties, the differences between which are minor and primarily relate to implementation nuances. For example, a spy is a type of mock that is created manually, without the use of ready-made tools, which we'll discuss in the next section.
The main types of stabilizers (stabs) include several categories, each with its own characteristics and applications. The main types of stabilizers include: mechanical stabilizers, which ensure the stability of products during operation; electronic stabilizers, which allow you to adjust the operating parameters of stabilizers; and software stabilizers, which are used to process data and maintain system stability. Each of these types of stubs plays a vital role in various industries, including manufacturing, electronics, and software, ensuring reliability and performance.
- A dummy is a simplified version of a stub that is used as a placeholder. Dummy's behavior is ignored; it is needed to satisfy compiler requirements. A simple example of a dummy is the popular beginner program "Hello, world."
- Fake is a more complex object. It not only fills space in the code, but can also return different values depending on the scenario. An example of a fake is a test collection that simulates the operation of a database.
When testing software, regardless of the type of test object used, be it a mock, spy, stub, fake, or dummy, they are often all combined under the general name "mocks." This is an established practice in development, although in fact, each of these types of test objects has its own characteristics and purposes. Now that you have this information, you will be able to more accurately interpret terminology and apply appropriate techniques to improve the quality of your code. Properly understanding the differences between test objects will help you create more effective and reliable tests, which in turn will improve the quality of your software product.
When to Use Mock
There is a well-established practice in the development field according to which components should be replaced with mocks only in cases where they are not directly part of the main program, but with which it interacts. Such systems include databases, mail servers, file systems, message buses, and similar elements. In scientific terminology, these components are called "external dependencies changed outside the process". Using mocks allows you to simplify testing and increase the reliability of software by isolating the logic under test from external factors.
Replacing dependencies with mocks located inside the application makes no sense. Tests created for such objects become brittle and focused on implementation details rather than the final result. A more effective approach is to use real objects for testing, which allows one to evaluate the system's behavior as a whole and avoid problems associated with imperfect mocks. Testing original objects provides a more reliable and robust result.

Read also:
Unit tests are a software testing method in which individual modules or components of code are checked for correct operation. They allow developers to ensure that each part of the program functions as intended and help identify errors early in the development process. Unit tests play a key role in the software development process, as they contribute to code quality and speed up debugging.
It is important to note that unit tests help reduce the time required to test and implement new features and provide confidence in the stability of existing functionality. Regular use of unit tests during development helps improve code documentation, as tests serve as an example of its expected behavior.
Furthermore, unit tests facilitate easier code refactoring, allowing developers to make changes without fear of breaking existing functionality. As a result, the use of unit tests not only improves software quality but also makes the development process more efficient and transparent.
This approach has its advantages, but it misses an important point: external systems can also be an implementation element. For example, if a database functions exclusively with our application, it should be treated as an integral part of the system and tested at the development stage. This will ensure more complete and reliable operation of the application as a whole, taking into account all interactions with external components.
Vladimir Khorikov's article "When to Mock" (translated on Habr) presents more advanced approaches to using mocks. The author argues that only unmanaged and non-process dependencies should be mocked. This means that mocks should be applied to components over which you have no direct influence. This approach significantly improves the efficiency of testing and reduces the likelihood of errors.
We are testing the PaymentProcessor class, which is responsible for processing incoming payments. This class interacts with an external payment gateway, implemented in the PaymentGateway class, to which we do not have direct access. Testing the functionality of PaymentProcessor is important to ensure correct transaction processing and system reliability.
PaymentGateway is an unmanaged dependency, as it interacts with external payment systems to which we have limited access. Since testing the payment gateway using real money is undesirable, it is advisable to consider creating a mock object to simulate it. This will allow us to effectively test integration with the payment gateway without risking funds and ensure testing stability. Using mock objects in such cases contributes to a more flexible and secure development process, allowing us to focus on the functionality of the application.
There are two main benefits here:
- We isolate our class from external systems. Our goal is to test how PaymentProcessor processes payments, not how external payment systems work. Mocking PaymentGateway isolates PaymentProcessor testing from real payment systems.
- We can implement any test scenarios. For example, configure the PaymentGateway mock to emulate payment system responses for successful and unsuccessful payments.
It is important to note that mocking internal components can be justified in certain situations. For example, if you plan to integrate component B to test component A, but for some reason this is not possible – for example, the team lead has not yet selected a library or it takes a significant amount of time to work with JSON – then it is acceptable to use a mock for component B. This will allow you to continue developing and testing component A without delays. However, it should be remembered that overusing this approach can lead to problems down the road, so it should be used sparingly.
Mock Testing Tools
After studying the theory, it's time to move on to practice. Let's start by building a core set of tools for mock testing in Python. This will enable effective testing and ensure the reliability of your software solutions.
Unittest is part of the Python standard library and provides a powerful framework for developing and running tests. It allows you to create mock objects that reproduce the behavior of dependent components, allowing you to isolate the code under test and improve its quality. However, it's worth noting that unittests are not designed to simulate external services, which limits their use in some scenarios. Using unittests helps improve software reliability and simplifies the debugging process, making it an essential tool in the developer's arsenal.
Advantages: Convenient syntax for generating mocks.
Disadvantages: Limited capabilities for simulating external servers, as Unittest does not offer effective tools for creating mock servers and emulating external HTTP services. This can make it difficult to test interactions with APIs and other remote resources, which in turn can negatively impact the quality of testing and the reliability of the application.
Pytest.mock is a powerful module of the Pytest library that offers advanced capabilities for creating mock objects compared to Unittest. Although using Pytest.mock may seem more complex, its functionality can significantly simplify the testing process in Python. This module provides flexible tools for simulating the behavior of objects, which makes testing more efficient and allows you to avoid dependencies on external resources.
The advantages of using mocks include their flexible behavior configuration and the ability to verify method calls. This allows you to more accurately simulate the behavior of dependencies in tests, which, in turn, contributes to higher code quality and reliability. Mocks help developers isolate the components under test, which makes it easier to identify errors and improves the debugging process.
The disadvantages of using this programming language include its complex syntax, which can be difficult for beginners. Learning the fundamentals and rules of coding takes time and effort. This can be a barrier for those just starting their programming journey. Therefore, it is important to consider this aspect when choosing technologies for training and development.

Reading is an important aspect of our lives that contributes to personal growth and development. It helps expand horizons, improve vocabulary and develop critical thinking. Books, articles, and scientific research provide a unique opportunity to gain new knowledge and perspectives. Furthermore, reading can be a great way to relax and escape the daily grind. Regular reading improves concentration, memory, and analytical skills, making it not only engaging but also rewarding. It's important to find time for reading in your schedule to maximize the benefits and enrich your inner world.
Pytest Guide: Python Code Testing
Pytest is one of the most popular Python testing frameworks, providing powerful code validation tools. It allows developers to easily write tests while maintaining a high degree of flexibility and simplicity. In this guide, we'll explore the key features of Pytest and its advantages for testing your Python applications.
Pytest supports many test types, including functional and integration tests. Its simple and intuitive structure allows you to quickly create test functions, greatly simplifying the development process. You can start with simple tests and then move on to more complex ones, including testing asynchronous code and working with fixtures for data preparation.
One of the main advantages of Pytest is its extensibility. Plugins allow you to add new features and improve testing functionality. There are many ready-made plugins that can help you in your work, for example, for CI/CD integration, support for various report formats, and much more.
Pytest also offers powerful tools for analyzing test results. You can easily track test success and get complete information about failures, which helps you quickly find and fix bugs in your code.
To get started with Pytest, simply install it via pip and create simple test files. We recommend adhering to generally accepted naming standards, which will make it easier to find and run tests. Using Pytest not only speeds up the testing process but also improves the quality of your code, promoting more robust software development.
In conclusion, Pytest is a powerful tool for testing Python code, offering developers flexibility, simplicity, and numerous opportunities to improve the quality of their software products.
Postman is a powerful tool for testing APIs and generating HTTP requests. It allows you to create mock servers, which is convenient for emulating API behavior and testing interactions with external services. Using Postman simplifies the development and testing process, providing developers with the necessary tools to effectively work with APIs.
Advantages:
- Intuitive interface for creating HTTP requests and testing APIs.
- Ability to create mock servers to emulate API behavior.
- Good integration with various services and testing tools.
- Programming language independence.
The disadvantages of using certain products or services can significantly influence consumer choice. Firstly, this may be a high price, which makes the product inaccessible to a wide audience. Secondly, some goods may be of low quality, which leads to rapid wear and tear and the need for replacement. Also worth noting is a lack of functionality when the product does not meet user expectations or does not solve the stated problems. In addition, a lack of support from the manufacturer or limited information about the product can cause dissatisfaction among customers. Finally, difficulty in use or installation can be a serious obstacle for many users. All these aspects are important to consider when selecting and evaluating products on the market.
- Not suitable if you need to mock anything other than APIs and HTTP requests.
- The free version only allows 1000 mocks per month.

Getting ready
In the following sections, we'll focus on creating mocks that will simulate two main types of dependencies: external and internal. Before you begin this task, it's important to have all the necessary infrastructure properly set up. This will provide a solid foundation for testing and development.
Before you begin, make sure you have Python installed. If you don't have it, download the installer from the official Python website and follow the installation instructions. The installation process is no more complicated than installing a browser. After the installation is complete, it is recommended to verify that the installation was successful. To do this, open a command prompt, on Windows this can be done by pressing the Win + R key combination, and enter:
If Python is installed on your device, you will be able to see its version. To do this, open a command prompt or terminal and enter the command «python —version» or «python3 —version». This will allow you to quickly determine which version of Python is active on your computer. Make sure you are using the latest version for the best experience with libraries and development tools.

If the command is not formulated correctly, cmd will not be able to understand your intentions. This can lead to errors and difficulties when executing commands. Therefore, it's important to formulate commands accurately and take proper syntax into account to ensure correct execution of command line queries. Correct use of the command line allows you to effectively manage the system and perform the necessary operations without errors.

We recommend using an integrated development environment (IDE), which will greatly simplify the process of working with code, eliminating the need to manually specify system paths and imports. In our case, we recommend PyCharm. Installing this IDE is easy: just download the installation file from the official website and follow the step-by-step instructions. Using PyCharm will increase your productivity and simplify the development of Python projects.
In this section, we will look at how to create mocks in Postman. If you are a tester working with APIs, you are sure to encounter this powerful tooling environment. Installing Postman is easy: just download the installation file from the official website, and the program will guide you through the installation process. Mocks in Postman help you simulate API behavior, which simplifies testing and allows you to focus on verifying the logic of your application.
Mock Testing with Internal Dependencies
Our goal is to test the order processor. This will allow us to identify potential errors and improve the functionality of the system. Effective testing of the order processor will ensure high-quality customer service and optimize business processes.
Create a project named test_example, which will match the name of the root folder in PyCharm. Within this project, create a file called order.py, which will be the object of our testing.
This text describes two classes: NotificationService, which is responsible for sending notifications, and Order, which is responsible for processing orders. Note that one of the methods of the Order class depends on NotificationService. However, in a situation where the NotificationService implementation is unavailable, but the functionality of the Order class needs to be tested, we can create a mock object for NotificationService. To do this, create a new folder called tests in the test_example folder and a file called test_order.py in it.
In the example given, the mock_notification_service mock object was created using the spec_set parameter. This parameter allows you to define a list of methods and attributes that the mock must have. We clearly specified that the mock would contain only the methods and attributes defined in the NotificationService class. Thus, with a single line of code, we created a mock with complex logic, significantly simplifying the testing process and increasing its efficiency.
In this test, we verify that the send_notification method is called with the correct arguments. To run the test_order.py file, click the Run button.

The test is considered successful if the send_notification method The mock_notification_service mock object is called once with the given arguments. In this case, we get the following message:

Let's run additional tests for our Order class. The following test functions need to be added to the TestOrder class:

Let's assume that our test class always reports positive results, regardless of actual achievements. Let's check this. To do this, we will add a test function to the TestOrder class, which will intentionally fail.
If all steps are performed correctly, the result will be presented as follows:

Mock Testing with External Dependencies
Let's consider a situation where your component needs to interact with a resource you don't have direct access to. In this case, we'll create a mock remote server that will provide your application with weather data. This approach allows you to test functionality without connecting to a real API, which will significantly simplify and speed up the development process. The mock server will simulate the responses you expect to receive, thereby providing realistic testing of your component.
Create a new project called MockServerTest. In the root directory of the project, create two files: weather_app and mock_server. Also, create a folder called tests. First, you need to implement the WeatherService class in the weather_app file.
Our class implements a single method, get_temperature(), which makes a GET request and receives a response from the server. This functionality is sufficient for the tasks at hand.
Creating a mock server is an important step in developing an application. To do this, open the mock_server file and paste the following code into it. This will allow you to simulate the behavior of the server-side portion of the application, simplifying testing and developing client-side logic. Ensure that the code meets your requirements and correctly handles the necessary requests. A mock server will help you effectively test the functionality of your application, regardless of the state of the real server.
Create the test_weather_app_with_mock_server file in the tests folder. This file will be used to write tests that test the functionality of your weather application using the mock server. The mock server will allow you to simulate responses from a real API, simplifying the testing process. Ensure that the tests cover all key aspects of the application, including retrieving weather data, error handling, and displaying information to the user. Use appropriate testing and mocking libraries to make the process more efficient and reliable.
To ensure our server launches successfully before testing, we need to create a preconfiguration file. To do this, create a file named conftest.py in the tests folder. This file will be used to configure tests and initialize the necessary components, ensuring the server operates correctly during testing.
The construct with the @ symbol at the beginning represents a fixture, which is a pre-prepared piece of data used in testing. This fixture contains a function that calls the run_mock_server method imported from MockServerHandler and initiates its execution. This code organization allows for efficient management of test data and simplifies the testing process, which contributes to higher quality software development.
The test_get_temperature_with_mock function creates an object of the WeatherService class, which is imported from the weather_app module. This function compares the pre-defined expected temperature (expected_temperature) with the server response. This allows you to test the correct operation of the weather service and ensure that it returns the correct data. Testing with mock objects helps isolate functionality and ensures the reliability of your application.
Open Postman and switch to the Mock Servers tab on the left. Then click the "Create Mock Server" button to create a new mock server.

On the next On the screen, leave the request method unchanged (GET). In the URL field, enter "weather" and leave the response code at 200. In the "response body" field, insert a JSON-like structure: {"temperature": 20}. After that, click «Next».

Specify the server name and leave the rest of the fields unchanged. Click the Create Mock Server button.

The server is configured, and its name is displayed on the left. Now you need to get the server URL. To do this, click the «Copy URL» button.

We will replace the localhost address with this URL in our mock_server and update the address bar in the weather_app application to the new mock server address.
Run weather_app_test_with_mock_server. The expected output should meet the specified criteria. Ensure that the tests run correctly and provide the desired weather information. For optimal results, ensure all dependencies and settings are configured correctly. This will allow you to get accurate data and improve the performance of the application.

The server will automatically terminate its work upon completion of testing.
Add a new function to A test file for additional testing. This will help improve the quality and reliability of your code. Ensure the function is clearly defined and meets testing requirements. Ensure it effectively tests the necessary aspects of your application to ensure its correct operation.
We are launching a new project aimed at solving current problems in our industry. We strive to offer innovative solutions that will help improve the efficiency and quality of services provided. Our team of professionals uses modern technologies and advanced techniques to ensure maximum customer satisfaction.
We pay special attention to analyzing market needs and adapting our offerings to user requests. Each stage of development is thoroughly tested to ensure reliability and security. Our goal is to become an industry leader by providing high-quality solutions that meet the highest standards.
Stay tuned to stay informed about the latest news and achievements of our project. We are confident that by working together we can achieve significant results and contribute to the development of our field.

Now let's move on to creating a failing test. The following function must be added to the test file:
Introducing error handling into the server code (mock_server) will improve its functionality. To do this, modify the do_GET method in the MockServerHandler class. These changes will allow the server to return error responses when necessary, which will increase its resilience and simplify the debugging process. Configuring error handling will also allow for more accurate testing of client applications interacting with this server.
At the beginning of your file, add import code that looks like this: from http.server import BaseHTTPRequestHandler. This import will allow you to use the BaseHTTPRequestHandler class to create custom HTTP request handlers in your project. Make sure this code is placed at the very top of your file to avoid runtime errors.
Verification is an important step in any process, allowing you to identify errors and flaws. High-quality verification helps ensure high standards and compliance with stated requirements. It is important to pay attention to every aspect, be it text, a product, or a service. Effective review involves several key elements: careful content analysis, structure analysis, and assessment of the content's relevance to the target audience and its needs. Regular reviews contribute to improved quality and efficiency, which in turn leads to improved results and customer satisfaction. Don't forget that systematic testing is the key to success and growth.
Everything worked out: what shouldn't work really doesn't It works.
Results
Congratulations on mastering the creation and use of mocks. In real-world test scenarios, a tester's creativity opens up opportunities for more interesting and varied applications of different types of test doubles. We hope that the next time you encounter mocks, you'll be confident in your knowledge and be able to navigate this tool easily. If you're interested in developing tests in Python, we recommend checking out our free Pytest course, which will help deepen your skills and improve the quality of your testing.
Learn more about programming and coding in our Telegram channel. Subscribe to stay up-to-date with the latest news, tips, and useful content!
Also read:
- Postman: What is it and how to use it
- "First an internship — then an offer, money, success": How a historian became a tester
- Popular questions and tasks at tester interviews

