具有side_efffect的模拟类属性

时间:2020-10-19 14:07:51

标签: python django unit-testing python-mock

在访问模拟对象的属性时如何引发异常?

我尝试对以下代码段执行相同的操作

import unittest
from unittest import TestCase
from django.core.exceptions import ObjectDoesNotExist
from unittest.mock import MagicMock, PropertyMock


def function_to_call_one_to_one(model_instance):
    try:
        return model_instance.artist.name
    except ObjectDoesNotExist:
        # calling `model_instance.artist` will raise `ObjectDoesNotExist` exception
        return "raised `ObjectDoesNotExist`"


class TestObjectDoesNotExist(TestCase):
    def test_artist_name(self):
        model_instance = MagicMock()
        model_instance.artist.name = "Michael Jackson"
        name = function_to_call_one_to_one(model_instance)
        self.assertEqual(name, "Michael Jackson")

    def test_artist_name_with_error(self):
        model_instance = MagicMock()
        model_instance.artist = PropertyMock(side_effect=ObjectDoesNotExist)
        res = function_to_call_one_to_one(model_instance)
        self.assertEqual(res, "raised `ObjectDoesNotExist`")


if __name__ == '__main__':
    unittest.main()

不幸的是,测试功能test_artist_name_with_error(...)失败,并显示消息

AssertionError:!='提高了ObjectDoesNotExist'

如何为这种情况编写单元测试?

注意:我见过这样的帖子,Python: Mock side_effect on object attribute,但是对我来说不起作用。我希望这个例子是一个可复制的例子。

1 个答案:

答案 0 :(得分:1)

很好的问题。这是您可能已忽略的docs的一部分:

由于模拟属性的存储方式,您无法直接将PropertyMock附加到模拟对象。相反,您可以将其附加到模拟类型对象。

这有效:

type(model_instance).artist = PropertyMock(side_effect=ObjectDoesNotExist)