尽管FACTORY_DJANGO_GET_OR_CREATE,为什么FactoryBoy会从SubFactory创建一个新对象

时间:2013-06-20 06:28:01

标签: django unit-testing factory-boy

我刚刚开始在Django中使用factory boy。它具有设置FACTORY_DJANGO_GET_OR_CREATE,这意味着如果已存在新对象,则不会创建新对象。但是当我要求现有SubFactory对象的现有对象时,尽管有此设置,它仍会创建一个未使用的对象。

例如,在一个全新的项目中,我尝试过:

# models.py
from django.db import models

class A(models.Model):
    name = models.CharField(max_length=10)

class B(models.Model):
    name = models.CharField(max_length=10)
    a = models.ForeignKey(A)

# factories.py
import factory

from . import models

class AFactory(factory.DjangoModelFactory):
    FACTORY_FOR = models.A
    FACTORY_DJANGO_GET_OR_CREATE = ('name',)

    name = factory.Sequence(lambda n: 'A-{0}'.format(n))

class BFactory(factory.DjangoModelFactory):
    FACTORY_FOR = models.B
    FACTORY_DJANGO_GET_OR_CREATE = ('name',)

    name = factory.Sequence(lambda n: 'B-{0}'.format(n))
    a = factory.SubFactory(AFactory)

现在:

from factories import *

a = AFactory(name="Apple")
models.A.objects.all()
# one object
b = BFactory(a__name="Apple", name="Beetle")
models.B.objects.all()
models.A.objects.all()
# one A object, one B object
b = BFactory(name="Beetle")
models.B.objects.all()
models.A.objects.all()
# still one B object, but now a new, unused A object too

然后对BFactory的最终调用已成为类A的新对象,即使名为Beetle的B对象已存在(并且未重新创建) 。为什么,以及如何停止创建这个新的A对象?

(我知道我可以通过打电话来解决这个问题:

b = BFactory(name="Beetle", a__name="Apple")

但在我的实际使用案例中,我有几个依赖关系和层次结构级别,以这种方式提供额外的冗余参数很麻烦 - 我似乎无法获得正确的参数组合。)

谢谢!

3 个答案:

答案 0 :(得分:1)

当我还有一个具有B外键的C类时,上面是一个问题。当我创建一个新的CFactory对象时:

c = CFactory(name="Cat", b__name="Beetle")

它还会创建一个新的未使用的A对象。

我发现这个解决方案很简单:相反,像这样制作新的CFactory对象:

c = CFactory(name="Cat", b=b)

其中bB个对象或BFactory个对象。

答案 1 :(得分:1)

您可以致电使用:

a = SubFactory(AFactory, name='Reuse this model A instance')

这样,以下两个调用是相同的:

BFactory()
BFactory(a__name='Reuse this model A instance')

答案 2 :(得分:0)

我相信在get_or_create之后,无论如何,subfactory都会进入。

虽然不确定s9lution,但这不是我遇到的用例。依赖于get_or_create的IMHO灯具具有太大的魔力潜力。如果你有一个复杂的测试用例,那么另一种选择(总是创建)可能会更乏味一些,但更安全