I have django 1.11 app and I want to write unit test for my solution.
I want to test registration date feature.
model.py:
class User(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
registration_date = models.DateTimeField(auto_now_add=True)
def get_registration_date(self):
return self.registration_date
I'm using also django-boy for models factories: factories.py
class UserFactory(factory.DjangoModelFactory):
class Meta:
model = models.User
first_name = 'This is first name'
last_name = 'This is last name'
registration_date = timezone.now()
test.py
def test_get_registration_date(self):
user = factories.UserFactory.create()
self.assertEqual(user.get_registration_date(), timezone.now())
Problem is that I recived AssertionError
:
AssertionError: datetime.datetime(2018, 4, 17, 9, 39, 36, 707927, tzinfo=<UTC>) != datetime.datetime(2018, 4, 17, 9, 39, 36, 708069, tzinfo=<UTC>)
auto_now_add. Automatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it's not just a default value that you can override. So even if you set a value for this field when creating the object, it will be ignored.
auto_now - updates the value of field to current time and date every time the Model. save() is called. auto_now_add - updates the value with the time and date of creation of record.
The universal way to use Factory Boy
with Django
with DateTime
with auto_now_add=True
_fake_time
to freeze time during object creationfrom contextlib import suppress
from factory.django import DjangoModelFactory
from freezegun import freeze_time
from functools import partial
class CustomDjangoModelFactory(DjangoModelFactory):
@classmethod
def create(cls, _fake_time=None, **kwargs):
wrapper = partial(freeze_time, time_to_freeze=_fake_time) if _fake_time else suppress
with wrapper(_fake_time):
return super().create(**kwargs)
CustomDjangoModelFactory
import factory
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=255)
created = models.DateTimeField(auto_now_add=True)
class MyModelFactory(CustomDjangoModelFactory):
name = factory.Sequence(lambda n: "Model No. %03d" % n)
class Meta:
model = MyModel
_fake_time
or withoutmy_model1 = MyModelFactory(name='first', _fake_time='2020-12-1')
my_model2 = MyModelFactory(name='second', _fake_time=datetime(2020, 11, 30))
my_model3 = MyModelFactory(name='third')
You can use mock
:
import pytz
from unittest import mock
def test_get_registration_date(self):
mocked = datetime.datetime(2018, 4, 4, 0, 0, 0, tzinfo=pytz.utc)
with mock.patch('django.utils.timezone.now', mock.Mock(return_value=mocked)):
user = factories.UserFactory.create()
self.assertEqual(user.get_registration_date(), mocked)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With