simple model(models.py):
from django.db import models
class MyModel(models.Model):
start_date = models.DateField()
simple factory(test_factories.py):
from datetime import date
import factory
from .models import MyModel
class MyModelFactory(factory.django.DjangoModelFactory):
class Meta:
model = MyModel
start_date = date.today()
In manage.py shell
:
In [1]: from datetime import date
In [2]: from freezegun import freeze_time
In [3]: from polls.test_factories import MyModelFactory
In [4]: date.today()
Out[4]: datetime.date(2017, 8, 16)
In [5]: with freeze_time(date(1999,9,9)):
...: print(date.today())
...: m = MyModelFactory()
...: print(m.start_date)
...:
1999-09-09
2017-08-16
current date is 2017-08-16 and fake date is 1999-09-09. Inside freeze_time
, date.today()
give fake date but factoryboy is not affected by freezegun. It still give real current date.
Is this bug? If yes, bug with factoryboy or freezegun?
How to solve this? In other words, How to make factoryboy give fake date? (For now, I use MyModelFactory(start_date=date.today())
to create model with fake date.)
freezegun version: 0.3.9
factoryboy version: 2.8.1
The issue is that date.today()
is evaluated when python parses the factory declaration; and factory_boy only receives the resulting date instance.
This is part of the core Python behavior — and can't be overridden by factory_boy.
The proper solution for this problem would be to use a factory.LazyFunction
declaration:
class MyModelFactory(factory.django.DjangoModelFactory):
class Meta:
model = MyModel
# Note that we simply pass a callable.
start_date = factory.LazyFunction(date.today)
You might also want to take a look at factory.fuzzy.FuzzyDate
which would generate random dates in a given timespan.
LazyFunction(date.today)
doesn't solve the problem because date.today
is bound before the time is frozen (datetime.date
gets overridden with FakeDate
).
LazyFunction(lambda: date.today())
does solve the problem because it's evaluated after freezing time.
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