是否可以对属性进行side_effect?如果我查看Mock文档,它似乎只能在对象方法上使用。
我正在尝试测试以下内容:
def get_object(self):
try:
return self.request.user.shop
except Shop.DoesNotExist:
return None
我希望Shop提出一个DoesNotExist异常。
猜猜也许我不够清楚,但我在谈论空洞模拟库。
答案 0 :(得分:13)
值得注意的是,现在有PropertyMock
类:
>>> m = MagicMock()
>>> p = PropertyMock(side_effect=ValueError)
>>> type(m).foo = p
>>> m.foo
Traceback (most recent call last):
....
ValueError
答案 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。