首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何模拟在with语句中使用的open (使用Python中的模拟框架)?

如何模拟在with语句中使用的open (使用Python中的模拟框架)?
EN

Stack Overflow用户
提问于 2009-08-17 19:26:51
回答 7查看 162.4K关注 0票数 253

如何使用unittest.mock测试以下代码

代码语言:javascript
复制
def testme(filepath):
    with open(filepath) as f:
        return f.read()
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-05-24 22:56:44

在mock 0.7.0中,实现这一点的方法发生了变化,它最终支持模拟python协议方法(魔术方法),特别是使用MagicMock:

http://www.voidspace.org.uk/python/mock/magicmock.html

作为上下文管理器模拟打开的示例(来自模拟文档中的示例页面):

代码语言:javascript
复制
>>> open_name = '%s.open' % __name__
>>> with patch(open_name, create=True) as mock_open:
...     mock_open.return_value = MagicMock(spec=file)
...
...     with open('/some/path', 'w') as f:
...         f.write('something')
...
<mock.Mock object at 0x...>
>>> file_handle = mock_open.return_value.__enter__.return_value
>>> file_handle.write.assert_called_with('something')
票数 146
EN

Stack Overflow用户

发布于 2014-12-12 02:19:23

要将mock_open用于一个简单的文件read() (原始的mock_open代码片段already given on this page更适合写入):

代码语言:javascript
复制
my_text = "some text to return when read() is called on the file object"
mocked_open_function = mock.mock_open(read_data=my_text)

with mock.patch("__builtin__.open", mocked_open_function):
    with open("any_string") as f:
        print f.read()

注根据mock_open的文档,这是专门针对read()的,因此不能用于常见的模式,例如for line in f

使用python 2.6.6 / mock 1.0.1

票数 14
EN

Stack Overflow用户

发布于 2016-06-28 04:45:53

最上面的答案是有用的,但我对它进行了一些扩展。

如果您想根据传递给open()的参数来设置文件对象(as f中的f )的值,这里有一种方法:

代码语言:javascript
复制
def save_arg_return_data(*args, **kwargs):
    mm = MagicMock(spec=file)
    mm.__enter__.return_value = do_something_with_data(*args, **kwargs)
    return mm
m = MagicMock()
m.side_effect = save_arg_return_array_of_data

# if your open() call is in the file mymodule.animals 
# use mymodule.animals as name_of_called_file
open_name = '%s.open' % name_of_called_file

with patch(open_name, m, create=True):
    #do testing here

基本上,open()将返回一个对象,with将对该对象调用__enter__()

要正确模拟,我们必须模拟open()以返回模拟对象。然后这个模拟对象应该模拟对它的__enter__()调用(MagicMock将为我们做这件事),以返回我们想要的模拟数据/文件对象(因此是mm.__enter__.return_value)。通过上面的两个mock方法,我们可以捕获传递给open()的参数并将它们传递给我们的do_something_with_data方法。

我将整个模拟文件作为字符串传递给open(),我的do_something_with_data如下所示:

代码语言:javascript
复制
def do_something_with_data(*args, **kwargs):
    return args[0].split("\n")

这会将字符串转换为列表,因此您可以像处理普通文件一样执行以下操作:

代码语言:javascript
复制
for line in file:
    #do action
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1289894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档