在单元测试中模拟 open(file_name)
我有一个源代码,可以打开 csv 文件并设置标题 价值关联。源代码如下:
def ParseCsvFile(source):
"""Parse the csv file.
Args:
source: file to be parsed
Returns: the list of dictionary entities; each dictionary contains
attribute to value mapping or its equivalent.
"""
global rack_file
rack_type_file = None
try:
rack_file = source
rack_type_file = open(rack_file) # Need to mock this line.
headers = rack_type_file.readline().split(',')
length = len(headers)
reader = csv.reader(rack_type_file, delimiter=',')
attributes_list=[] # list of dictionaries.
for line in reader:
# More process to happeng. Converting the rack name to sequence.
attributes_list.append(dict((headers[i],
line[i]) for i in range(length)))
return attributes_list
except IOError, (errno, strerror):
logging.error("I/O error(%s): %s" % (errno, strerror))
except IndexError, (errno, strerror):
logging.error('Index Error(%s), %s' %(errno, strerror))
finally:
rack_type_file.close()
我正在尝试模拟以下语句
rack_type_file = open(rack_file)
如何模拟 open(...) 函数?
I have a source code that opens a csv file and sets up a header to
value association. The source code is given below:
def ParseCsvFile(source):
"""Parse the csv file.
Args:
source: file to be parsed
Returns: the list of dictionary entities; each dictionary contains
attribute to value mapping or its equivalent.
"""
global rack_file
rack_type_file = None
try:
rack_file = source
rack_type_file = open(rack_file) # Need to mock this line.
headers = rack_type_file.readline().split(',')
length = len(headers)
reader = csv.reader(rack_type_file, delimiter=',')
attributes_list=[] # list of dictionaries.
for line in reader:
# More process to happeng. Converting the rack name to sequence.
attributes_list.append(dict((headers[i],
line[i]) for i in range(length)))
return attributes_list
except IOError, (errno, strerror):
logging.error("I/O error(%s): %s" % (errno, strerror))
except IndexError, (errno, strerror):
logging.error('Index Error(%s), %s' %(errno, strerror))
finally:
rack_type_file.close()
I am trying to mock the following statement
rack_type_file = open(rack_file)
How do I mock open(...) function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
诚然,这是一个老问题,因此一些答案已经过时了。
在当前版本的
mock
库中有一个专门为此目的而设计的便利函数。它的工作原理如下:文档位于此处。
This is admittedly an old question, hence some of the answers are outdated.
In the current version of the
mock
library there is a convenience function designed for precisely this purpose. Here's how it works:Documentation is here.
要模拟使用 mox 打开的内置函数,请使用
__builtin__
模块:请注意,
__builtins__
并不总是模块,它可以是 dict 类型,请使用__builtin__< /code>(不带“s”)模块引用系统内置方法。
有关
__builtin__
模块的更多信息:http://docs.python.org/library /内置.htmlTo mock built-in function open with mox use
__builtin__
module:Note that
__builtins__
is not always a module, it can be of type dict, please use__builtin__
(with no "s") module to refer to system built-in methods.More about
__builtin__
module: http://docs.python.org/library/builtin.html我喜欢用两种方法来做到这一点,具体取决于具体情况。
如果您的单元测试要直接调用 ParseCsvFile,我会向 ParseCsvFile 添加一个新的 kwarg:
然后您的单元测试可以传递不同的 open_func 以完成模拟。
如果您的单元测试调用其他一些函数,而这些函数又调用 ParseCsvFile,那么仅为了测试而传递 open_func 是很丑陋的。在这种情况下,我将使用 模拟模块。这使您可以按名称更改函数并将其替换为 Mock 对象。
There are two ways that I like to do this, depending on the situation.
If your unit test is going to call ParseCsvFile directly I would add a new kwarg to ParseCsvFile:
Then your unit test can pass a different open_func in order to accomplish the mocking.
If your unit test calls some other function that in turn calls ParseCsvFile then passing around open_func just for tests is ugly. In that case I would use the mock module. This lets you alter a function by name and replace it with a Mock object.
使用装饰器(Python3)很简单:
Is simple with decorator (Python3):
我冒昧地重写了您的示例函数:
假设您的函数位于名为
code.py
的文件中一个简单的测试用例是:
编辑:
使用 mox 0.53 在 2.6 上运行良好
I took the liberty of re-writing your sample function:
Assume your function is located in a file named
code.py
A simple test case would be:
EDIT:
Works fine on 2.6 using mox 0.53
嗨,我遇到了类似的问题,并且在不同的模拟库之间翻来覆去地撕扯着我的头发。我终于找到了一个令我满意的解决方案,也许它可以帮助你?最后我选择了 Mocker 库 http://labix.org/mocker 这里是模拟的代码open:
顺便说一句,我使用 Mocker 的原因是因为我正在测试一个使用 open 读取文件的函数,然后再次使用 open 用新数据覆盖同一文件。我需要做的是测试初始文件不存在的情况,因此设置一个模拟,第一次抛出 IOError,然后第二次工作。其设置如下所示:
希望这有帮助!
Hi I was having a similar problem, and was tearing my hair out flipping between different mocking libraries. I finally found a solution that I am happy with, and maybe it might help you? In the end I went with the Mocker library http://labix.org/mocker and here is the code for mocking open:
Incidentaly the reason I went with Mocker is because I was testing a function which used open to read a file, and then used open again to overwrite the same file with new data. What I needed to be able to do was test the case where the initial file didn't exist, so set up a mock, that threw an IOError the first time, and then worked the second time. The setup for which looked like this:
Hope this helps!
@mock.patch 装饰器(2.7 示例)
现在更容易了:
@mock.patch decorator (2.7 example)
This is now much easier: