我正在尝试使用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)
Run Code Online (Sandbox Code Playgroud)
然而with mo(…) as (fd, err)加薪AttributeError: __exit__.
with mo as (fd, err):
…
Run Code Online (Sandbox Code Playgroud)
后一段代码是我试图嘲笑的.但这不是我在代码中使用它的方式.对于那些真正感兴趣的人,我试图在PEP 343中模拟示例6 opened_w_error(),它处理打开文件和捕获错误.因此代码是:
with open_w_error(filename, 'r') as (fd, err):
…
Run Code Online (Sandbox Code Playgroud)
后者是我想要嘲笑的.
请注意,传递给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)
Run Code Online (Sandbox Code Playgroud)
编辑:如果您仍想调用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)
Run Code Online (Sandbox Code Playgroud)
问题是当你调用mo(..)它返回的对象时( tuple) 没有__enter__和__exit__属性。
要修复此分配mo为mo'sreturn_value以便仍然可以找到您在其上设置的上下文管理器属性。
@patch("__main__.opened_w_error")
def test_get_recipe_file(self, mo):
mo.return_value = mo
mo.__enter__ = Mock(return_value=(Mock(), None))
mo.__exit__ = Mock(return_value=None)
with mo('file', 'r') as (fd, err):
print(fd)
print(err)
mo.assert_called_once_with('file', 'r') # Should be True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6548 次 |
| 最近记录: |