I'm trying to write unit tests for a django app that does a lot of datetime operations. I have installed mock to monkey patch django's timezone.now for my tests.
While I am able to successfully mock timezone.now when it is called normally (actually calling timezone.now() in my code, I am not able to mock it for models that are created with a DateTimeField with default=timezone.now.
I have a User model that contains the following:
from django.utils import timezone
...
timestamp = models.DateTimeField(default=timezone.now)
modified = models.DateTimeField(default=timezone.now)
...
def save(self, *args, **kwargs):
if kwargs.pop('modified', True):
self.modified = timezone.now()
super(User, self).save(*args, **kwargs)
My unit test looks like this:
from django.utils import timezone
def test_created(self):
dt = datetime(2010, 1, 1, tzinfo=timezone.utc)
with patch.object(timezone, 'now', return_value=dt):
user = User.objects.create(username='test')
self.assertEquals(user.modified, dt)
self.assertEquals(user.timestamp, dt)
assertEquals(user.modified, dt) passes, but assertEquals(user.timestamp, dt) does not.
How can I mock timezone.now so that even default=timezone.now in my models will create the mock time?
Edit
I know that I could just change my unit test to pass a timestamp of my choice (probably generated by the mocked timezone.now)... Curious if there is a way that avoids that though.
Usermodel? It is very important to know at what point the binding for default value is taking place. - Oleksiy