Python:模拟对象属性的side_effect

时间:2011-04-24 08:11:13

标签: python

是否可以对属性进行side_effect?如果我查看Mock文档,它似乎只能在对象方法上使用。

我正在尝试测试以下内容:

def get_object(self): 
    try:
        return self.request.user.shop
    except Shop.DoesNotExist:
        return None

我希望Shop提出一个DoesNotExist异常。

猜猜也许我不够清楚,但我在谈论空洞模拟库。

http://www.voidspace.org.uk/python/mock/index.html

5 个答案:

答案 0 :(得分:13)

值得注意的是,现在有PropertyMock类:

>>> m = MagicMock()
>>> p = PropertyMock(side_effect=ValueError)
>>> type(m).foo = p
>>> m.foo
Traceback (most recent call last):
....
ValueError

该示例为taken from the official site

答案 1 :(得分:4)

您还可以尝试使用 PropertyMock 作为new_callable参数修补相关字段。

示例:

from unittest import TestCase
import mock
from django import models
from django.core.exceptions import ObjectDoesNotExist

class Foo(models.Model):
    # ...
    @property
    def has_pending_related(self):
        try:
            return self.related_field.is_pending
        except ObjectDoesNotExist:
            return False

class FooTestCase(TestCase):
    # ...
    @mock.patch.object(Foo, 'related_field', new_callable=mock.PropertyMock)
    def test_pending_related(self, related_field):
        related_field.side_effect = ObjectDoesNotExist
        foo = Foo()
        self.assertFalse(foo.has_pending_related)

答案 2 :(得分:3)

是的,你可以使用它的属性:

In [1]: class ShopDoesNotExist(Exception):
   ...:     pass
   ...:

In [2]: class User(object):
   ...:     @property
   ...:     def shop(self):
   ...:         raise ShopDoesNotExist
   ...:
   ...:

In [3]: u = User()

In [4]: u.shop
---------------------------------------------------------------------------
ShopDoesNotExist                          Traceback (most recent call last)

答案 3 :(得分:1)

作者发表了一篇关于这个问题的博客文章。我选择了第一个看起来像这样的解决方案:

class UserMock(Mock):
    @property
    def shop(self):
        raise Shop.DoesNotExist()

http://www.voidspace.org.uk/python/weblog/arch_d7_2010_11_20.shtml#e1196

答案 4 :(得分:0)

顺便说一句,如果您要测试 <dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <scope>test</scope> </dependency> 作为AttributeError,则可以使用side_effect参数并将其设置为空列表(即spec) 。假设您正在尝试创建一个[]对象,该对象在访问属性Mock时抛出AttributeError

foo

请参见Documentation

spec:这可以是字符串列表,也可以是用作模拟对象规范的现有对象(类或实例)。如果传入一个对象,则通过在该对象上调用dir来形成字符串列表(不支持的魔术属性和方法除外)。 访问此列表中未包含的任何属性都会引发AttributeError。