python - 使用模拟来修补不存在的属性

标签 python unit-testing testing mocking pytest

我正在尝试测试一个上下文管理器,它使用一个类,该类使用一些 __getattr__ 魔法来解析类中实际上不存在的几个属性。我遇到了一个问题,在尝试修补类时 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

关于python - 使用模拟来修补不存在的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29951859/

相关文章:

python - 滚动 Matplotlib 颜色条

python - 从 Pandas Dataframe 创建 Numpy 数组时丢失字符串

c++ - 升压测试应用程序初始化

performance - Jmeter - 获取网站的确切可访问时间

testing - Spectron:启动应用程序后无法与 Electron 应用程序上的元素交互

testing - 如何设置PhantomJS的浏览器语言

python - 无法通过迭代器设置数组值

python - 为什么 Python 3 允许 "00"作为 0 的文字,但不允许 "01"作为 1 的文字?

java - 如何使 Maven 单元测试代码覆盖工作

我们可以使用 googletest (gtest) 来测试 C 代码吗