我正在尝试使用 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/