factoryboy不会覆盖django模型属性

时间:2016-05-20 07:47:11

标签: python django factory-boy

我正在尝试通过factory_boy覆盖自定义Django模型属性以进行测试。但它似乎只是采取模型的默认行为。工厂男孩不能改变自定义属性的默认行为吗?

这是我写的基本测试:

models.py

class Session(models.Model):
    name = models.CharField(max_length=100)

    @property
    def foo(self):
        return method_not_callable_in_testing()

def method_not_callable_in_testing():
    return 42

SessionFactory.py

class SessionFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Session

    name = "session"
    foo = 1337

tests.py : class TestSession(TestCase):

def test_custom_attribute_overwritten_by_factoryboy(self):
    session = SessionFactory.create()
    self.assertEquals(session.foo, 1337)

运行测试时出现以下错误:

F
======================================================================
FAIL: test_custom_attribute_overwritten_by_factoryboy (bar.tests.TestSession)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/sh4ke/repos/foo/bar/tests.py", line 10, in test_custom_attribute_overwritten_by_factoryboy
    self.assertEquals(session.foo, 1337)
AssertionError: 42 != 1337

1 个答案:

答案 0 :(得分:1)

TL;博士

factory_boy可以更改"自定义属性",(我假设您的意思是 not django Fields),但它无法更改读取 - 只是属性,这是你想要做的。

更多信息

您的问题是您正在尝试使用工厂为只读属性设置属性。粗略地说,factory_boy和django的组合意味着对SessionFactory()的调用正在进行:

session = Session()
session.foo = 1337

但是我不希望这个工作,因为除非你声明@foo.setter方法@property假设你想要一个只读属性,所以当你试图设置它时会引发属性错误

奇怪的是为什么你没有看到那个错误,结果是django悄悄地压制它!它通过执行foo看到您的模型具有getattr(session, 'foo')属性,但它已将包括setattr 的整个事物包裹在try: except AttributeError:内,因此,当它检测并尝试设置一个根本不存在的属性时,它也会捕获并静静地忽略尝试设置只读属性的失败情况。

我怀疑这是一个错误...所以可能会尝试用django社区来提升它。