4

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

这是我写的一个基本测试:

模型.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

会话工厂.py

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

    name = "session"
    foo = 1337

测试.py:类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
4

1 回答 1

1

tl;博士

factory_boy 可以更改“自定义属性”(我假设您的意思是那些不是django的Fields),但它不能更改只读属性,这是您正在尝试做的。

更多信息

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

session = Session()
session.foo = 1337

但我不希望这会起作用,因为除非您声明该@foo.setter方法@property假定您需要一个只读属性,因此当您尝试设置它时会引发属性错误。

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

我怀疑这是一个错误......所以可能会尝试与 django 社区一起提出它。

于 2016-05-20T15:42:06.073 回答