Testing mock and monkeypatch
Mocking
A mock object replaces and imitates a real object during the test. It is a flexible and powerful tool for improving your test quality.
MagicMock
The unittest.mock is the library for mocking in Python. It provides an easy way to introduce mocks into your tests. For example, the main.py file:
The test_main.py file:
from unittest import mock
from main import delay
def test_function_has_called():
mock_function = mock.MagicMock()
delay(3, mock_function)
mock_function.assert_called_once()
Mocking With an Unittest mock.patch
The unittest.mock provides a powerful tool for mocking objects — patch(), which looks up an object in a given module and replaces that object with a mock.
Usually, we use the patch() as a decorator or a context manager to provide a scope in which you can mock the target object.
If you want to mock an object for the duration of your entire test function, you can use the patch() as a function decorator.
An example of using the patch():
# test_main.py
from unittest import mock
from main import delay
@mock.patch("time.sleep")
def test_function_has_called(mocked_sleep):
delay(100, lambda: None)
mocked_sleep.assert_called_once_with(100)
Mocking With a Context Manager
Sometimes, you’ll need to use the patch() as a context manager rather than a decorator, for example, when:
you only want to mock an object for a part of the test scope; you are already using too many decorators or parameters, which hurt your test’s readability.
For example:
from unittest import mock
from main import delay
def test_function_has_called():
with mock.patch("time.sleep") as mocked_sleep:
delay(100, lambda: None)
mocked_sleep.assert_called_once_with(100)
Pytest Monkeypatch
The pytest also provided the mocking mechanism — monkeypatch, which is analog for unittest.mock. For example, the main.py file:
import os
def get_current_path():
current_path = os.getcwd()
return current_path # Return the current directory
The test_main.py file: