Trying to Mock Datetime.Date.Today(), But Not Working

Trying to mock datetime.date.today(), but not working

There are a few problems.

First of all, the way you're using mock.patch isn't quite right. When used as a decorator, it replaces the given function/class (in this case, datetime.date.today) with a Mock object only within the decorated function. So, only within your today() will datetime.date.today be a different function, which doesn't appear to be what you want.

What you really want seems to be more like this:

@mock.patch('datetime.date.today')
def test():
datetime.date.today.return_value = date(2010, 1, 1)
print datetime.date.today()

Unfortunately, this won't work:

>>> test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.macosx-10.6-universal/egg/mock.py", line 557, in patched
File "build/bdist.macosx-10.6-universal/egg/mock.py", line 620, in __enter__
TypeError: can't set attributes of built-in/extension type 'datetime.date'

This fails because Python built-in types are immutable - see this answer for more details.

In this case, I would subclass datetime.date myself and create the right function:

import datetime
class NewDate(datetime.date):
@classmethod
def today(cls):
return cls(2010, 1, 1)
datetime.date = NewDate

And now you could do:

>>> datetime.date.today()
NewDate(2010, 1, 1)

Python: Mocking datetime.date.today()

It is just because by @patch('mymodule.dt.date') you are patching the original date reference in datetime module. In this context dt.date(2016, 1, 10) is a MagicMock where the name is date().

From this you have today_string_dt_date() will return a date().strftime() MagicMock.

I admit that is a little bit twisted and it is for this kind of things that I try avoid complicated paths in patch: my rules are

  1. Try to patch just the root reference.
  2. If you cannot follow 1 (module with from a import b) just patch the module reference and never browse from it.

Python: How do I mock datetime.utcnow()?

in your test file:

from yourfile import get_report_month_key
import mock
import unittest
from datetime import datetime

class TestCase(unittest.TestCase):

@mock.patch('yourfile.datetime')
def test_dt(self, mock_dt):
mock_dt.utcnow = mock.Mock(return_value=datetime(1901, 12, 21))
r = get_report_month_key()
self.assertEqual('190112', r)

How to mock python's datetime.now() in a class method for unit testing?

You could use freezegun :

from freezegun import freeze_time

def test():
assert datetime.datetime.now() != datetime.datetime(2012, 1, 14)
with freeze_time("2012-01-14"):
assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)
assert datetime.datetime.now() != datetime.datetime(2012, 1, 14)

It basically mocks datetime module calls.

How to mock datetime.date.today() method in Django 1.5.5 tests

My investigations into this are in the question as a set of edits, but the long and short of this is that changes to the to_python method between 1.4 and 1.5 mean that anything that is neither a valid datetime.date nor datetime.datetime must be a string in order to pass through.

It looks (without too much further digging) as if the django.utils.encoding.smart_str method was removed in 1.5, and although it's been replaced by smart_text, this never made it into the to_python method.

I have raised a ticket in the django Trac instance, https://code.djangoproject.com/ticket/21523

I have also created a patch for this issue - but obviously this may never make it in (and the patch is for 1.5.x, which is already out-of-date, so I really wouldn't count on this making it in).

[EDIT 1: a solution!]

There is a solution ;-) - I have done a write up here - http://tech.yunojuno.com/mocking-dates-with-django - the key is overriding the FakeDate instancecheck method, so that when comparing a real datetime.date to a FakeDate you get True. I have put together a gist with some sample FakeDate classes and associated tests for reference - https://gist.github.com/hugorodgerbrown/7750432



Related Topics



Leave a reply



Submit