我正在尝试对采用文件路径并返回部分文件内容的解析函数进行单元测试。我希望能够为测试目的传递这些函数字符串数据。
我知道我能做到。reader()StringIO或文件句柄(例如csv.reader(StringIO(“my,data”)或csv)。reader(open(file)),但我看不到一种方法可以传递StringIO对象来代替文件路径,因为open(StringIO(“my,data”))失败了。同样,我希望在这些解析方法中使用文件打开/关闭逻辑,而不是在我的主要代码中,因为这会使我的主要代码变得混乱,也意味着我必须重新编写所有文件IO接口!
看来我的选择是:
import csv def parse_file(input): with open(input, 'r') as f: reader = csv.reader(f) output = [] for row in reader: #Do something complicated output.append(row) return output
对于未来寻找这个的其他人,我能够使用模拟来非常有效地做到这一点。
---- module: import_data.py -----
import csv
def read_file(input):
with open(input, 'r') as f:
reader = csv.reader(f)
output = []
for row in reader:
#Do something complicated
output.append(row)
return output
---- Unittests ----
import unittest
from io import StringIO
from mock import patch
from import_data import read_file
class TestImport(unittest.TestCase):
@patch('import_data.open')
def test_read_string(self, mock_file):
mock_file.return_value = StringIO(u"a,b\nc,d")
output = read_file(None)
self.assertEqual([['a', 'b'], ['c', 'd']], output)
def test_read_file(self):
filename = "sample_data.csv"
output = read_file(filename)
self.assertEqual([['a', 'b', 'c'],['d', 'e', 'f']], output)
如果不想更改接口以接受打开的文件对象,如StringIO
,请查看testfixtures模块。我用它来管理单元测试的文件和目录,尽管我通常更喜欢传入StringIO
对象。
如果你不喜欢这样,那么修补open()
听起来是一个合理的策略。我自己还没有尝试过。
你可以使用临时文件。
如果你真的不喜欢使用硬盘,你可以使用StringIO来替换你的文件,并重新定义内置的open
函数,就像这样:
import StringIO
import csv
#this function is all you need to make your code work with StringIO objects
def replaceOpen():
#the next line redefines the open function
oldopen, __builtins__.open = __builtins__.open, lambda *args, **kwargs: args[0] if isinstance(args[0], StringIO.StringIO) else oldopen(*args, **kwargs)
#these methods below have to be added to the StringIO class
#in order for the with statement to work
StringIO.StringIO.__enter__ = lambda self: self
StringIO.StringIO.__exit__ = lambda self, a, b, c: None
replaceOpen()
#after the re-definition of open, it still works with normal paths
with open(__file__, 'rb') as f:
print f.read(16)
#and it also works with StringIO objects
sio = StringIO.StringIO('1,2\n3,4')
with open(sio, 'rb') as f:
reader = csv.reader(f)
output = []
for row in reader:
output.append(row)
print output
这输出:
import StringIO
[['1', '2'], ['3', '4']]
遇到了另一个常见的问题,同时为Spring Batch编写单元测试和集成测试组件是如何模拟域对象。一个很好的例子是StepExecutionListener,如下所示: public class NoWorkFoundStepExecutionListener extends StepExecutionListenerSupport { public ExitStatus afterSte
我有以下两门课 我想对SampleTest getResult()进行单元测试,但我想在这里模拟Test1(),这样我就可以返回我在UnitTests中设置的任何值。这些课我都改不了。 我使用Mockito尝试了一些模式,但没有成功。 请提出一些好的建议。
问题内容: 我最近正在研究的程序中的一个常见任务是以某种方式修改文本文件。(嘿,我在Linux上。所有内容都是一个文件。我进行大规模的系统管理。) 但是代码修改的文件可能不存在于我的桌面盒中。而且,如果它在我的桌面上,我可能不想修改它。 我已经了解了Dive Into Python中的单元测试,并且很清楚我在测试将十进制转换为罗马数字的应用程序时想要做的事情(DintoP中的示例)。测试是完全独立
问题内容: 正如我们在http://docs.angularjs.org/tutorial/step_07中看到的那样, 建议通过e2e测试来完成路由测试, 但是,我认为’$ routeProvider’配置是通过单个函数function($ routeProvider)完成的,我们应该能够在不涉及浏览器的情况下进行单元测试,因为我认为路由功能不需要浏览器DOM。 例如, 当url为/ foo时,
我的“BBService”对象在这里为空 我是不是漏掉了什么?
我有一个springboot命令行应用程序,其中一个生产命令行参数是绝对基本路径。对于这个例子,我们称之为 “/var/batch/” 我正在为我的作品设定基本路径。像这样的yml文件有一个默认值。 公司: base Path:${base Path:/var/默认/} 然后,我有一个应用程序Config.java文件,它使用该基本路径来创建一堆类似的文件路径。 } 最后,文件路径像这样被传递到我