Suppose I have a module that checks a date is today (this is a simplified code)
# my_module.py
import datetime
def is_today(input_date):
return input_date == datetime.date.today()
I want to test this function
# test_my_module.py
import datetime
from unittest.mock import patch
from my_module import is_today
def test_is_today():
cases = [
{'input_date': datetime.date(2022, 5, 14), 'expected_output': True, '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:
with patch('my_module.datetime.date.today', lambda x: case['today']):
assert is_today(case['input_date']) == case['expected_output']
But when I run pytest test_my_module.py
, I get FAILED test_my_module.py::test_is_today - TypeError: can't set attributes of built-in/extension type 'datetime.date'
Any idea how to do it?
Also does anybody know how to do it with pytest-mock and which method is prefered?
CodePudding user response:
You could patch the entire datetime
:
for case in cases:
class FakeDatetime:
class date:
def today(): return case['today']
with patch('my_module.datetime', FakeDatetime)
The limitation is that you lose all other functionality of datetime
.