在Factory Boy的对象工厂中重写模型@property

时间:2012-10-19 09:09:42

标签: python django unit-testing factory-boy

我想找到一种方法来正确测试我的代码与Factory Boy。

有一个模型,像这样:

from django.db import models

class MyModel(models.Model):
    param1 = <some field>
    param1 = <some field>
    param1 = <some field>

    @property
    def is_smth(self):
        <some complicated code that returns boolean>

这个型号有一个工厂:

import factory

class MyModelFactory(factory.DjangoModelFactory):
    param1 = <some value>
    param2 = <some value>
    param3 = <some value>

    # And here i need to "rewrite" property of the model
    # so that it would always return true

任何人都可以帮助我吗?我没有在工厂男孩的文档中找到关于这个的提及,我尝试过的各种变种似乎都不起作用。

3 个答案:

答案 0 :(得分:2)

你尝试过使用嘲笑吗?

def test_is_smith(self):
    mymodel = MyModel()
    with mock.patch('MyModel.is_smith', new_callable=mock.PropertyMock) as mocked_model:
        mocked_model.return_value = True
        self.assertTrue(mymodel.is_smith)

答案 1 :(得分:2)

正如Suganthi所说,你可以使用模拟。

但我提供了另一种解决方案:

 @classmethod
 def _create(cls, model_class, *args, **kwargs):   
     with mock.patch('MyModel.is_smth',
                     new_callable=mock.PropertyMock) as m:
         m.return_value = True
         return super()._create(model_class, *args, **kwargs)

在生成模型中只是模拟属性。它适用于factoryboy==2.5.2

答案 2 :(得分:0)

@StasEvseev的建议在我们的案例中不起作用。我最终利用了Factory Boy的post_generation钩子,因为我们的财产正在根据其他模型/数据计算价值。因此,构建@is_smth所需的数据将使其在调用该属性时按预期行为/评估:

class MyModelFactory(factory.DjangoModelFactory):
    ...

    @factory.post_generation
    def prepare_data_for_is_smth(self, create, extracted, **kwargs):
       # Populate/build here the models/fields needed for your
       # <some complicated code that returns boolean>.

创建工厂实例后执行后期生成挂钩。您可以使用extractedkwargs参数进一步自定义挂钩的行为,这些参数使用ATTR__SUBATTR格式在工厂类中传递(例如MyModelFactory(foo__bar=SOME_VALUE)