Python mock.patch自动指定具有属性的类

时间:2018-08-09 15:44:39

标签: python unit-testing mocking

我有一个用@property装饰器定义一些属性的类。当我修补该类并设置autospec = True时,我希望该属性的行为与规范相同

class MyClass(object):

    def __init__(self):
        self.will_not_be_mocked = 'not mocked'

    @property
    def will_be_mocked(self):
        return 'mocked property'

预期的行为:

当我访问实例上的will_be_mocked属性时,它的行为就像一个字符串属性。

>>> my_obj = MyClass()
>>> my_obj.will_be_mocked
'mocked property'

它不能被调用

>>> my_obj.will_be_mocked()
TypeError: 'str' object is not callable

因此该测试应通过:

with self.assertRaises(TypeError):
    my_obj.will_be_mocked()

观察到的行为:

当我修补类并设置autospec = True时,该属性将按预期包含在模拟的规范中,但是,它变成了MagicMock,并且可以调用。因此,任何试图执行该属性的代码都可以通过unittest并在生产中失败

@patch('__main__.MyClass, autospec=True)
def test_MyClass(self, MyClass):
    my_obj = MyClass()
    with self.assertRaises(TypeError):
        my_obj.will_be_mocked()

AssertionError: TypeError not raised

目标:

我想以一种易于使用autospec模拟的方式定义类。这就是为什么我试图定义属性而不是仅在__init__中添加属性的原因。

1 个答案:

答案 0 :(得分:0)

  

我想以一种易于使用autospec模拟的方式定义类

autospec通常用于模拟或伪造有关类的所有内容的情况。在您的示例中不是这样,打补丁或伪造1,只需要一个class属性。

这里是一个例子:

class Base(object):

@property
def cls_property(self):
    return 'cls_property'

class TestBase(unittest.TestCase):

def test_cls_property_with_property(self):
    """
    """
    with mock.patch('app.Base.cls_property', new_callable=mock.PropertyMock) as mock_cls_property:
        mock_cls_property.return_value = 'mocked_cls_property'
        base = Base()
        self.assertEqual(base.cls_property, 'mocked_cls_property')

        with self.assertRaises(Exception):
            base.cls_property()