使用模拟来修补不存在的属性
Using mock to patch a non-existing attribute
我正在尝试测试一个使用 class 的上下文管理器,它使用一些 __getattr__
魔法来解析 class 上实际上不存在的几个属性.我 运行 遇到一个问题,在尝试修补 class.
时 mock 引发了 AttributeError
我要修补的对象的简化示例。
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()
测试代码
def test_MyContextManager():
with patch.object(MyClass, 'myfunc', return_value=None) as mock_obj:
with MyContextManager():
pass
# Do some tests on mock object
这是我得到的错误:
AttributeError: <class 'MyClass'> does not have the attribute 'myfunc'
我能够做到这一点和 运行 测试,但它不会自动恢复属性(或者在这种情况下只是删除模拟属性):
MyClass.myfunc= Mock(return_value=None)
我愿意使用 mock 之外的另一个库来实现这一点。我也在使用 pytest。
要在此类测试中使用 patch,您应该使用 create
参数,如果不存在,该参数将强制创建属性。
所以你的测试应该像这样:
def test_MyContextManager():
with patch.object(MyClass, 'myfunc', create=True, return_value=None) as mock_obj:
with MyContextManager():
pass
我正在尝试测试一个使用 class 的上下文管理器,它使用一些 __getattr__
魔法来解析 class 上实际上不存在的几个属性.我 运行 遇到一个问题,在尝试修补 class.
我要修补的对象的简化示例。
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()
测试代码
def test_MyContextManager():
with patch.object(MyClass, 'myfunc', return_value=None) as mock_obj:
with MyContextManager():
pass
# Do some tests on mock object
这是我得到的错误:
AttributeError: <class 'MyClass'> does not have the attribute 'myfunc'
我能够做到这一点和 运行 测试,但它不会自动恢复属性(或者在这种情况下只是删除模拟属性):
MyClass.myfunc= Mock(return_value=None)
我愿意使用 mock 之外的另一个库来实现这一点。我也在使用 pytest。
要在此类测试中使用 patch,您应该使用 create
参数,如果不存在,该参数将强制创建属性。
所以你的测试应该像这样:
def test_MyContextManager():
with patch.object(MyClass, 'myfunc', create=True, return_value=None) as mock_obj:
with MyContextManager():
pass