There's a couple of stack overflow posts out there talking about mocking the open call in Python.这很好但是如果函数接受文件句柄或流对象而不是文件路径,它对我没有帮助。
到目前为止,我一直在使用的一个解决方案是cStringIO
个对象。然而,我遇到了一个问题。
如果我想测试我是否在某种类型的失败时正确记录文件名(例如,如果文件/流是空的并且您期望某种数据)
cStringIO
fd = cStringIO("")
fd.name = "testing/path" # Throws an AttributeError
我无法设置名称属性,因为cStringIO
和StringIO
是分组类。
如果切换为使用open_mock
with mock.patch('__main__.open', mock.mock_open(read_data=''), create=True) as m:
我遇到了
AttributeError: Mock object has no attribute 'tell'
此时感觉我必须使用临时文件,但如果可能的话,我想避免实际调用文件系统。
如何在不必在文件系统上创建实际文件的情况下测试接收文件句柄的函数?
答案 0 :(得分:1)
您可以使用Mock.return_value
:
tell
属性
import mock
def function_under_test(f):
f.tell() # => 0
f.read()
f.tell() # => 0
return f.name
with mock.patch('__main__.open', mock.mock_open(read_data=''), create=True) as m:
with open('/tmp/1') as f:
f.name = '/tmp/1'
f.tell.return_value = 0
assert function_under_test(f) == '/tmp/1'
答案 1 :(得分:0)
我沿着创建一个继承自StringIO的类的道路前进。我花了很多时间才想承认在Python2.7中,StringIO是一个旧样式类。
class MockFile(StringIO, object):
"""This is a work around for the fact that StringIO is a slotted class and
doesn't have a name attribute.
"""
name = None
def __init__(self, name, buffer_ = None):
super(MockFile, self).__init__(buffer_)
self.name = name