factoryboy不使用freezegun

时间:2017-08-16 16:22:13

标签: python django django-models factory-boy freezegun

简单模型(models.py):

from django.db import models

class MyModel(models.Model):
    start_date = models.DateField()

简单工厂(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()

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

当前日期是2017-08-16,假日期是1999-09-09。在freeze_time内,date.today()提供假日期,但工厂男孩不受冻结枪的影响。它仍然提供真实的当前日期。

  • 这个错误吗?如果是,那么出厂工厂或冻结枪的错误?

  • 如何解决这个问题?换句话说,如何让工厂男生给出假日期? (目前,我使用MyModelFactory(start_date=date.today())创建假日期模型。)

freezegun版本:0.3.9

factoryboy版本:2.8.1

2 个答案:

答案 0 :(得分:2)

问题是当python解析工厂声明时会评估date.today();和factory_boy只接收生成的日期实例。

这是Python核心行为的一部分 - 并且不能被factory_boy覆盖。

解决此问题的正确方法是使用factory.LazyFunction声明:

class MyModelFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = MyModel

    # Note that we simply pass a callable.
    start_date = factory.LazyFunction(date.today)

您可能还想查看factory.fuzzy.FuzzyDate,它会在给定的时间内生成随机日期。

答案 1 :(得分:2)

LazyFunction(date.today)不能解决问题,因为date.today在时间冻结之前已绑定(datetime.dateFakeDate覆盖)。

LazyFunction(lambda: date.today())确实解决了该问题,因为它是在冻结时间后评估的。