Difference Between Mock and Patch in Python

Difference Between Mock and Patch in Python

  1. Uses and Differences Between Mock and Patch Object Libraries in Python
  2. Conclusion

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:

  1. To conveniently substitute objects with mock objects (or other objects) and restore the previous state after completion or, in case of an exception, use the patch decorator/context manager function.
  2. The mock.patch creates mock 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 Paul Kenneth Mendoza avatar Marion Paul Kenneth Mendoza avatar

Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.

LinkedIn

Related Article - Python Unittest

  • Monkey Patching in Python