关于python:使用mock修补不存在的属性

Using mock to patch a non-existing attribute

我尝试测试一个上下文管理器,它使用一个类,该类使用一些__getattr__魔力来解析类中实际不存在的几个属性。我遇到了一个问题,mock在尝试修补类时引发了一个属性错误。

我要修补的对象的简化示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyClass(object):
    def __getattr__(self, attr):
        if attr == 'myfunc':
            return lambda:return None
        raise AttributeError('error')


class MyContextManager(object):
    def __init__(self):
        super(MyContextManager, self).__init__()
        self.myclass = MyClass()

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.myclass.myfunc()

测试代码

1
2
3
4
5
6
def test_MyContextManager():
    with patch.object(MyClass, 'myfunc', return_value=None) as mock_obj:
        with MyContextManager():
             pass

    # Do some tests on mock object

以下是我得到的错误:

1
AttributeError: <class 'MyClass'> does not have the attribute 'myfunc'

我可以这样做并运行测试,但它不会自动恢复属性(或者在本例中只删除模拟属性):

1
MyClass.myfunc= Mock(return_value=None)

我愿意使用除模拟之外的另一个库来实现这一点。我也在使用Pytest。


要在这些类型的测试中使用补丁,您应该使用create参数,如果不存在该参数将强制创建属性。

所以你的测试应该这样做:

1
2
3
4
def test_MyContextManager():
    with patch.object(MyClass, 'myfunc', create=True, return_value=None) as mock_obj:
        with MyContextManager():
             pass