Difference Between Mock and Patch in Python
Code development comes first in Test Parallel Development (TPD). Still, we write developed tests and execute them to verify the accuracy of the code (instead of running the code directly or using the console).
In Python, we have a process called unit testing and inside that are the mock
and patch
functions. This article will discuss the uses and the differences between the two roles.
Uses and Differences Between Mock
and Patch
Object Libraries in Python
In this article, we will not tackle unit testing as a whole but will focus more on mock
and patch
functions.
We use the mock
Python package to replace specific components of your system under test with mock
objects and make assertions about their usage. It is a component of the Python standard library and is accessible starting with Python 3.3 as unittest.mock
.
The unittest.mock
class eliminates the need for several stubs throughout your test suite. After performing a particular action, we can set assertions about which we used methods/attributes and arguments we called them.
It lets us specify return values and select needed features.
MagicDock can handle the Magic
objects, a subclass of Mock
. The Mock
and MagicMock
objects spontaneously generate characteristics and methods when we use them and log usage information.
Mocks are based on the action -> assertion
(that is, first let the mock
be used and then make assertions on it about the calls it received) pattern instead of the record -> replay
pattern used by many mocking frameworks. Additionally, the mock
module offers a decorator called patch()
that takes care of patching class and module level characteristics within the context of a test and a sentinel for producing unique instances.
Example Code:
from unittest.mock import patch
@patch("sample_module.sample_object")
def test_function(mock_object):
print(mock_object)
Output:
<MagicMock name='sample_object' id='1870192341512'>
The above code snippet is equivalent to the snippet below:
def test_function():
with patch("sample_module.sample_module") as mock_object:
print(mock_object)
The function allows us to replace any object with a mock
object to avoid calling the production code and check how the original object is called (if the object is a function). Using patch
(or similar methods) is preferred because this ensures the patch is reverted after the test (or after the context manager scope in the second case) so that other tests or programs are not affected.
Conclusion
We can take note of the following to help in our decision-making:
- To conveniently substitute objects with
mock
objects (or other objects) and restore the previous state after completion or, in case of an exception, use thepatch
decorator/context manager function. - The
mock.patch
createsmock
or derivative objects, which we can produce manually. Manually built are only used to repair local functions or other mocks that don’t require a reset.
Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.
LinkedIn