Reputation: 40664
It is the function I want to test
from datetime import datetime, timedelta, time
def my_func():
result_date = datetime.combine(datetime.now(), time.min) + timedelta(days=look_forward)
...
It is my unit test code
@patch('batch.mymodule.datetime')
def test_retrieve_data(self, mock_datetime):
mock_datetime.now = Mock(return_value=datetime.datetime.strptime('Feb 14 2015', '%b %d %Y'))
my_func
I think it works as intended. However the patch
also mocked the other method combine
. I will get this exception from my_func
later on
BadValueError: Expected datetime, got <MagicMock name='datetime.combine().__add__()' id='4494328976'>
I can fix it by adding this to the unit test:
mock_datetime.combine = datetime.datetime.combine
But it means I have to patch each individual method in datetime
if it is used.
Is there any better, simpler alternative?
Upvotes: 2
Views: 566
Reputation: 10101
This does not answer your question, but I just think it's worth mentioning another approach. For my project I used freezegun.
from freezegun import freeze_time
import datetime
class SomeTest(TestCase):
@freeze_time("2015-08-10 00:00:00")
def some_test_case(self):
print(datetime.now())
2015-08-10 00:00:00
Upvotes: 1
Reputation: 369074
Define datetime.datetime
subclass to use it as a mock object's class:
class MockDatetime(datetime.datetime):
fake_now = None
@classmethod
def now(cls):
return cls.fake_now
class TestFoo(unittest.TestCase):
@patch('mod.datetime', MockDatetime)
def test_retrieve_data(self):
MockDatetime.fake_now = datetime.datetime(2015, 2, 14)
my_func()
DEMO: http://asciinema.org/a/63nrqzrysunyeq76xl72f943k
Upvotes: 3