Trying to get mocking to work for datetime.date.today() I finally got it working, after reading this answer and this documentation. I did not get my original version to work though, and I was wondering if anyone could help me understand?
My original implementation was to call dt.date.today()
after importing datetime like this import datetime as dt
. This can be seen in mymodule.today_string_dt_date
. The testing was done by mocking mymodule.dt.date
(not possible to mock mymodule.dt.date.today
directly as it is a builtin), and setting mock.today.return_value = dt.date(2016,1,10)
after importing datetime
in the same way as in mymodule.py
(import datetime as dt
)
I then implemented a version that was importing date
directly (from datetime import date
) and created tests that was setting the mock.today.return_value
to both dt.date(2016,1,10)
and date(2016,1,10)
for both versions. All test versions but my original one are passing, as can be seen in the output from running py.test -v
It looks like using the same import scheme (import datetime as dt
) for both module and test and using that to create the mock return value (as in the test test_today_string_dt_date
) ruins the mock.
mymodule.py
import datetime as dt
from datetime import date
def today_string_dt_date():
return dt.date.today().strftime('%Y-%m-%d')
def today_string_date():
return date.today().strftime('%Y-%m-%d')
if __name__ == '__main__':
print(today_string_dt_date())
test_mymodule.py
import datetime as dt
from datetime import date
from unittest.mock import patch
import unittest
import mymodule
class MyTest(unittest.TestCase):
@patch('mymodule.dt.date')
def test_today_string_dt_date(self, mock_date):
mock_date.today.return_value = dt.date(2016, 1, 10)
assert mymodule.today_string_dt_date() == '2016-01-10'
@patch('mymodule.dt.date')
def test_today_string_dt_date_alt(self, mock_date):
mock_date.today.return_value = date(2016, 1, 10)
assert mymodule.today_string_dt_date() == '2016-01-10'
@patch('mymodule.date')
def test_today_string_date(self, mock_date):
mock_date.today.return_value = dt.date(2016, 1, 10)
assert mymodule.today_string_date() == '2016-01-10'
@patch('mymodule.date')
def test_today_string_date_alt(self, mock_date):
mock_date.today.return_value = date(2016, 1, 10)
assert mymodule.today_string_date() == '2016-01-10'
py.test output
=========================== test session starts ===========================
platform darwin -- Python 3.5.1, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
collected 4 items
test_mymodule.py::MyTest::test_today_string_date PASSED
test_mymodule.py::MyTest::test_today_string_date_alt PASSED
test_mymodule.py::MyTest::test_today_string_dt_date FAILED
test_mymodule.py::MyTest::test_today_string_dt_date_alt PASSED
================================ FAILURES =================================
____________________ MyTest.test_today_string_dt_date _____________________
self = <test_mymodule.MyTest testMethod=test_today_string_dt_date>
mock_date = <MagicMock name='date' id='4364815888'>
@patch('mymodule.dt.date')
def test_today_string_dt_date(self, mock_date):
mock_date.today.return_value = dt.date(2016, 1, 10)
> assert mymodule.today_string_dt_date() == '2016-01-10'
E AssertionError: assert <MagicMock name='date().strftime()' id='4353329528'> == '2016-01-10'
E + where <MagicMock name='date().strftime()' id='4353329528'> = <function today_string_dt_date at 0x10429ed90>()
E + where <function today_string_dt_date at 0x10429ed90> = mymodule.today_string_dt_date
test_mymodule.py:14: AssertionError
=================== 1 failed, 3 passed in 0.05 seconds ====================