Understanding different ways of mocking or patching a function

Viewed 29

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?
0 Answers
Related