Skip to content

Latest commit

 

History

History

ch_10_mocks

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

Chapter 10. Mocks.


AUT: Cards (To-Do List)

1. unittest.mock

import cards
from unittest import mock


def test_mock_path():
    with mock.patch.object(cards, "CardsDB") as MockCardsDB:
        MockCardsDB.return_value.path.return_value = "/mock_path"
        with cards.cli.cards_db() as db:
            print(f"db.path() = {db.path()}")

2. Syncing Mock and Implementation with Autospec

Issue: Mock objects are too flexible by default. They can accept misspelled methods, additional parameters, etc. It can cause mock drift. Mock drift occurs when the mocked interface changes and your mock does not.

Solution: use mock.patch.object(..., autospec=True)

3. Side Effects

mock_object.side_effect = Exception

4. Patch and where to Patch

  1. Mocking function (isleap()) in calendar using patch():
import calendar
from unittest.mock import patch

with patch('calendar.isleap'):
    print(calendar.isleap(1995))

...
# <MagicMock name='isleap()' id='2641389555088'>
  1. Mocking directly imported function:
from calendar import isleap
from unittest.mock import patch

with patch('calendar.is_weekday'):
    print(isleap(1995))

...
# False

Function won't be mocked because from calendar import is_weekday binds the real function to the local scope. So,even though you patch the function later, your mock will be ignored because you already have a local reference to the un-mocked function.

A good rule of thumb is to patch the object where it is looked up.

Working example of mocking directly imported function:

from calendar import isleap
from unittest.mock import patch

with patch('__main__.is_weekday'):
    print(isleap(1995))

...
# <MagicMock name='isleap()' id='2641389555088'>