Python:在对象属性上模拟 side_effect

32 投票
5 回答
20305 浏览
提问于 2025-04-16 16:19

有没有办法在一个属性上设置副作用?我看Mock的文档,好像只支持在对象的方法上设置。

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

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

我希望Shop能抛出一个DoesNotExist的异常。

可能我之前没说清楚,我指的是voidspace这个mock库。

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

5 个回答

4

你也可以尝试使用PropertyMock作为新的可调用参数,来修补相关的字段。

举个例子:

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)
31

值得一提的是,现在有一个叫做 PropertyMock 的类:

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

这个例子是从官方网站上拿来的。

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

撰写回答