Reputation: 2436
Suppose I have a module that checks if an input date is today. If it is today, shows tomorrow, otherwise, returns False
# my_module.py
import datetime
def is_today_return_tomorrow(input_date):
if input_date != datetime.date.today():
return False
return input_date + datetime.timedelta(1)
The purpose of this example is having a function that have both datetime.date.today()
and datetime.timedelta(1)
and it is a simplified code to explain the question.
Now I want to test this code using pytest.
# test_my_module.py
import datetime
from unittest.mock import patch
from my_module import is_today_return_tomorrow
def test_is_today():
cases = [
{'input_date': datetime.date(2022, 5, 14), 'expected_output': datetime.date(2022, 5, 15), 'today': datetime.date(2022, 5, 14)},
{'input_date': datetime.date(2022, 5, 14), 'expected_output': False, 'today': datetime.date(2022, 5, 12)}
]
for case in cases:
class FakeDatetime:
class date:
def today(): return case['today']
with patch('my_module.datetime', FakeDatetime)
assert is_today_return_tomorrow(case['input_date']) == case['expected_output']
This is the answer explained in this question how to mock patch `today` in pytest python?
However, there is now a problem. Because I am patching my_module.datetime
, it no longer has timedelta
method. How should I address this problem?
Upvotes: 0
Views: 648
Reputation: 16815
You can just patch datetime.date
instead of the whole datetime
module:
@pytest.mark.parametrize("input_data, expected_output, today",
[(datetime.date(2022, 5, 14),
datetime.date(2022, 5, 15),
datetime.date(2022, 5, 14)),
(datetime.date(2022, 5, 14),
False,
datetime.date(2022, 5, 12))])
def test_is_today(input_data, expected_output, today):
with patch('my_module.datetime.date') as date:
date.today.return_value = today
assert is_today_return_tomorrow(input_data) == expected_output
This leaves other datetime
functions like timedelta
intact and can use them.
Note that I have replaced the iteration over test cases by standard pytest
parametrization, as you are using pytest
anyway.
Upvotes: 2