Skip to content
Advertisement

How to use patch.object() correctly

I’m trying to get my head around Mock and patch(), but I’m stuck on a somewhat simple example. Say I have the following function in main.py, which tests if it’s a weekday or not.

from datetime import datetime

def is_weekday():
    today = datetime.today()
    return (0 <= today.weekday() < 5)

I want to run my test with two possible outcomes: either False if I mock Saturday or Sunday or True if it’s a weekday. Now, I’m clearly not mocking anyting when calling main.is_weekday so my test currently fails as it’s the weekend. How can I fix that?

from unittest.mock import Mock, patch
import pytest
import main

def test_weekday():
    datetime = Mock()
    tuesday = datetime(year=2019, month=1, day=1)
    datetime.today.return_value = tuesday
    with patch.object(datetime, "main.is_weekday", tuesday) as mock_method:
        expected = True
        actual = main.is_weekday() # how do I mock datetime.today()?
        assert actual == expected

Advertisement

Answer

The essential problem is that you’re not patching datetime in your main module. The first argument to patch.object is the thing you want to patch, and since you’re passing in your datetime Mock object, that doesn’t do you any good.

I would restructure your test like this:

from unittest.mock import Mock, patch
from datetime import datetime
from mockito import when, ANY

import main


def test_weekday():
    testdate = datetime(year=2019, month=1, day=1)
    with patch("main.datetime", wraps=datetime) as mock_datetime:
        mock_datetime.today.return_value = testdate
        assert main.is_weekday()


def test_weekend():
    testdate = datetime(year=2019, month=1, day=5)
    with patch("main.datetime", wraps=datetime) as mock_datetime:
        mock_datetime.today.return_value = testdate
        assert not main.is_weekday()

Here, we’re replacing main.datetime with a mock object, and then configuring it such that calling datetime.today() in the main module will return a specific date.

Then we test that the code works as expected for both weekdays and weekends.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement