python - 上下文管理器的模拟失败,出现 AttributeError : __exit__

标签 python mocking

我正在尝试使用 Mock 修补一些上下文管理器功能,以便我可以测试代码在给定好的、坏的和垃圾输入的情况下是否能做出明智的事情。这是带有 with 语句的测试代码。补丁已在我的代码中的正确位置完成。

@patch("__main__.opened_w_error")
def test_get_recipe_file(self, mo):
    mo.return_value = (Mock(), None)
    mo.__enter__ = Mock(return_value=None)
    mo.__exit__ = Mock(return_value=None)
    with mo(…) as (fd, err):  # AttributeError: __exit__ is raised here.
        print(fd)
        print(err)

但是 with mo(…) as (fd, err) 引发了 AttributeError: __exit__

documentation for mocking magic methods说明您应该将其用作

with mo as (fd, err):
    …

后一段代码是我要模拟的。 但这不是我在代码中使用它的方式。对于那些真正感兴趣的人,我正在尝试模拟 example 6 opened_w_error() in PEP 343它处理打开文件和捕获错误。因此代码是:

with open_w_error(filename, 'r') as (fd, err):
    …

后者是我想 mock 的。

最佳答案

请注意,您传递给 with 语句的对象应该具有 __enter____exit__ 方法,返回值来自__enter__ 用于 as 结构。在您的情况下,您正在调用 mo(...),它返回 (Mock(), None),这不是上下文管理器。您应该将此返回值移至 __enter__ 方法。

@patch("__main__.opened_w_error")
def test_get_recipe_file(self, mo):
    mo.__enter__ = Mock(return_value=(Mock(), None))
    mo.__exit__ = Mock(return_value=None)
    with mo as (fd, err):
        print(fd)
        print(err)

编辑:如果您仍想调用 mo,则将其返回值设置为上下文管理器。

@patch("__main__.opened_w_error")
def test_get_recipe_file(self, m_opened_w_error):
    mo = Mock()
    mo.__enter__ = Mock(return_value=(Mock(), None))
    mo.__exit__ = Mock(return_value=None)
    m_opened_w_error.return_value = mo
    with m_opened_w_error(...) as (fd, err):
        print(fd)
        print(err)

关于python - 上下文管理器的模拟失败,出现 AttributeError : __exit__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39163207/

相关文章:

python - 了解 Mathematica 轮廓线提取

python - 在定义的类中使用方法

java - 如何模拟私有(private)静态最终字段

使用 Espresso + MockK 的 Android UI 测试在模拟器上使用 SIGSEGV 崩溃,在物理设备上很好

android - 无法运行 2 个连续的测试(需要但未调用实际上,与此模拟的交互为零)

typescript - 如何使用 Jest 在 TypeScript 中模拟导入的函数?

python - 名称错误 : name "webdriver" is not defined

python - 如何在maya中查询当前视口(viewport)渲染器

python 元类不记得新值

C# 为对象列表创建 Mock Configuration.GetSection (“Section:SubSection” )