为什么我的模拟属性没有返回指定的值但是MagicMock对象和我的模拟方法返回了预期的值?

时间:2017-11-10 10:24:56

标签: python django python-2.7 unit-testing mocking

我无法按预期运行测试。我试图模拟两个属性的返回值和一个测试的方法,但我得到一个MagicMock对象而不是获得所需的返回值。

我无法弄清楚如何做到这一点。最让我恼火的是,模拟方法按预期工作,但对于这两个属性却没有。 这是我遇到的问题,因为我正在使用属性或因为外键关系或我做了一些基本错误的事情?

我使用的是Django 1.8,Python2.7,model-mommy,unittests,mock

以下是我的代码的一些片段,我希望它们足以理解这种情况:

App1称为生产者

# In producers.models.Producer:

    @property
    def is_valid(self):
        # do stuff
        return True

App2称为客户

# In customers.models.Customer:

    @property
    def is_valid(self):
        # do stuff
        return True

    def is_allowed_to_purchase_from_producer(producer):
        # do stuff
        return True

App3称为购买

# In purchases.models

class Purchase(BaseModel):

    producer = ForeignKey('Producers.Producer', related_name="purchase")
    customer = ForeignKey('Customers.Customer', related_name="purchase")


    def clean(self):
        if not self.producer.is_valid:
            rasie ValidationError
        if not self.customer.is_valid:
            raise ValidationError
        if not self.customer.is_allowed_to_purchase_from_producer(self.producer):
            raise ValidationError

对购买模型的清洁方法的测试

# test_models.py, in PurchaseTestSuite

    @mock.patch('producers.models.Producer.is_valid')
    @mock.patch('customers.models.Customer.is_valid')
    @mock.patch('customers.models.Customer.is_allowed_to_purchase_from_producer')
    def test__clean(self, mock__customer_is_allowed_to_purchase, mock__customer_is_valid, mock__producer_is_valid):

        mock__producer_is_valid.return_value = True
        mock__customer_is_valid.return_value = False
        mock__customer_is_allowed_to_purchase.return_value = False

        valid_purchase.clean()
  • 实际上返回了producer.is_valid:<MagicMock name='is_valid' id='4465040784'>
  • 的值
  • 实际上返回了值 customer.is_valid:<MagicMock name='is_valid' id='4465109520'>
  • for customer.is_allowed_to_purchase_from_producer(producer):False

当声明属性是否已被调用时,我得到False但是对于方法我得到了True。不同之处在哪里?我没看到什么?

1 个答案:

答案 0 :(得分:0)

感谢Daniel Roseman的评论并链接到PropertyMock我设法弄清楚如何让测试运行。

  

用于作为属性或其他描述符的模拟   类。 PropertyMock提供 get ()和 set ()方法   可以在获取时指定返回值。

因此,对于上面的示例,简单的解决方案是对所有属性使用PropertyMock:

@mock.patch('producers.models.Producer.is_valid', new_callable=mock.PropertyMock)

其余部分保持与上例相同。

我希望如果有人遇到类似问题,这会有所帮助。