【问题标题】:factoryboy not overriding django model propertiesfactoryboy 没有覆盖 django 模型属性
【发布时间】:2016-05-20 07:47:11
【问题描述】:

出于测试目的,我正在尝试通过 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: 类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

【问题讨论】:

    标签: python django factory-boy


    【解决方案1】:

    tl;博士

    factory_boy 可以更改“自定义属性”,(我假设您的意思是 not django Fields),但它不能更改只读属性,这就是您的身份努力去做。

    更多信息

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

    session = Session()
    session.foo = 1337
    

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

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

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

    【讨论】:

    • 我从字面上回答了这个问题,但如果你真正想要的是一种在测试中模拟方法的方法,你应该使用mock 模块(python 3 中的unittest.mock)和@ 987654332@函数,应该可以帮你做你想做的事。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 2018-10-04
    相关资源
    最近更新 更多