I am tyring to understand what are the differences between the following three ways of creating a mock function for usage in testing.
Suppose you have the following application.py(from this link):
# application.py
from time import sleep
def is_windows():
# This sleep could be some complex operation instead
sleep(5)
return True
def get_operating_system():
return 'Windows' if is_windows() else 'Linux'
and the following test_application.py
# test_application.py
from unittest.mock import patch
import application
from application import get_operating_system
# * Non-mocked test behaviour
# def test_get_operating_system():
# assert get_operating_system() == 'Windows'
# Mocked test behaviour
# In this example, I mock the slow function and return True always
# - 1) 'mocker' fixture provided by pytest-mock
def test_get_operating_system_1(mocker):
mocker.patch('application.is_windows', return_value=True)
assert get_operating_system() == 'Windows'
# - 2) 'monkeypatch' fixture
def test_get_operating_system_2(monkeypatch):
def mock_is_windows(*args, **kwargs):
return True
monkeypatch.setattr(application, 'is_windows', mock_is_windows)
assert get_operating_system() == 'Windows'
# - 3) 'patch' from unittest.mock
@patch.object(application, 'is_windows', return_value=True)
def test_get_operating_system_3(mock_system):
assert get_operating_system() == 'Windows'
These tests all pass, but seem to behave differently, although from the pytest-mock pytest, and unittest.mock documentations I cannot fully understand those differences.
Therefore these are my "simple" questions:
- What are the differences between test 1, 2, 3?
- When is it more convenient to use each one of them?
- What other strategies can I use to patch tests?