How to mock up one method in a module other than mock up the whole module
My purpose is to mock up the return value of utcnow
. I am using pytest
and pretty new on it.
The method in my_file.py
and under module my_module
:
import datetime
def get_date_info() -> Tuple[int, str]:
now_epoch = int(datetime.utcnow().strftime("%s"))
# do something with now_epoch
calculated_epoch = ...
# another variable relies on datetime
another_variable = datetime.fromtimestamp(calculated_epoch).strftime("%H")
return (now_epoch, another_variable)
My pytest
test for the method:
from my_module.my_file import get_date_info
import datetime
import mock
@mock.patch("my_module.my_file.datetime")
def test_get_date_info():
mock_dt.utcnow = mock.Mock(return_value=datetime.datetime(2002, 1, 1))
actual_epoch, actual_another_variable = get_date_info()
# assert code here
The returned actual_epoch
is accurate with the mocked date, unfortunately the below code didn't return str but <MagicMock name='datetime.fromtimestamp().strftime()' id='140249763149088'>
datetime.fromtimestamp(calculated_epoch).strftime("%H")
Does anyone know what causes the issue and how can I fix it?
Solution 1:
The issue is you are mocking only utcnow
, so when utcnow is invoked in the actual code - it returns your mocked value. You have to mock datetime.fromtimestamp
as well for it to return your mocked value.
eg:
mock_dt.fromtimestamp = mock.Mock(return_value=datetime.datetime(2002, 1, 1))