Mock_open CSV文件没有获取任何数据

dra*_*aB1 9 python csv mocking

我正在尝试对一段代码进行单元测试:

def _parse_results(self, file_name):
    results_file = open(file_name)
    results_data = list(csv.reader(results_file))
    index = len(results_data[1])-1
    results_file.close()
    return float(results_data[1][index])
Run Code Online (Sandbox Code Playgroud)

通过使用mock_open如此:

@mock.patch('path.open', mock.mock_open(read_data='test, test2, test3, test4'))
def test_parse_results(self):
    cut = my_class(emulate=True)
    self.assertEqual(VAL, cut._parse_results('file'))
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是我在运行csv.reader时没有得到任何数据.如果我运行results_file.readlines(),我得到'test,test2,test3,test4',这意味着mock_open正常工作.但是当我运行csv.reader(results_file)时,我丢失了所有数据.

nim*_*smi 8

这是因为mock_open没有实现文件具有的所有功能,尤其是没有实现某些功能csv

mock_open实现方法read()readline()readlines()和工作既作为一个功能,当被称为上下文管理器(https://docs.python.org/3/library/unittest.mock.html#mock-open),而csv.reader与作品...

任何支持迭代器协议并在每次__next__()调用其方法时都返回字符串的对象—文件对象和列表对象均适用

https://docs.python.org/3/library/csv.html#csv.reader

请注意,mock_open它不会实现__next__()方法,StopIteration到达终点时也不会引发,因此它不适用于csv.reader

@Emily在回答中指出,解决方案是将文件转换为其行列表。这是可能的,因为mock_open实现了readlines(),并且如文档所述,生成的列表适合阅读csv.reader


小智 4

这也确实让我着迷,而且是一场噩梦。要使用您的示例代码,这可以工作

results_data = list(csv.reader(results_file.read()))
Run Code Online (Sandbox Code Playgroud)

这有效

results_data = list(csv.reader(results_file.readlines()))
Run Code Online (Sandbox Code Playgroud)

但这不起作用

results_data = list(csv.reader(results_file))
Run Code Online (Sandbox Code Playgroud)

使用Python 3.4。

这似乎与记录的界面相反,csv.reader所以也许专家可以详细说明原因。