简体   繁体   English

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

[英]Mock_open CSV file not getting any data

I am trying to unit test a piece of code: 我正在尝试对一段代码进行单元测试:

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])

by using mock_open like so: 通过使用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'))

The problem I am running into is that I do not get any data when running csv.reader. 我遇到的问题是我在运行csv.reader时没有得到任何数据。 If I run results_file.readlines() I get 'test, test2, test3, test4' which means that mock_open is working properly. 如果我运行results_file.readlines(),我得到'test,test2,test3,test4',这意味着mock_open正常工作。 But when I run csv.reader(results_file) I lose all the data. 但是当我运行csv.reader(results_file)时,我丢失了所有数据。

This is because mock_open doesn't implement every feature that a file has, and notably not some of the ones that csv needs. 这是因为mock_open没有实现文件所具有的每个功能,特别是csv需要的功能。

mock_open implements the methods read() , readline() and readlines() , and works both as a function and when called as a context manager ( https://docs.python.org/3/library/unittest.mock.html#mock-open ), whereas csv.reader works with… mock_open实现方法read()readline()readlines() ,并且作为函数和作为上下文管理器调用时都可以工作( https://docs.python.org/3/library/unittest.mock.html#模拟打开 ),而csv.reader使用...

any object which supports the iterator protocol and returns a string each time its __next__() method is called — file objects and list objects are both suitable 任何支持迭代器协议的对象,每次调用__next__()方法时返回一个字符串 - 文件对象和列表对象都适用

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

Note that mock_open doesn't implement the __next__() method, and doesn't raise StopIteration when the end is reached, so it won't work with csv.reader . 请注意, mock_open不实现__next__()方法,并且在到达结尾时不会引发StopIteration ,因此它不适用于csv.reader

The solution, as @Emily points out in her answer, is to turn the file into a list of its lines. 正如@Emily在她的回答中指出的那样,解决方案是将文件转换为其行列表。 This is possible because mock_open implements readlines() , and the resulting list is suitable for reading into csv.reader as the documentation says. 这是可能的,因为mock_open实现readlines()并将得到的名单适用于读取到csv.reader的文件说。

This really got me too, and was a nightmare to pinpoint. 这真的让我受益匪浅,并且是一场噩梦。 To use your example code, this works 要使用您的示例代码,这是有效的

results_data = list(csv.reader(results_file.read()))

and this works 这很有效

results_data = list(csv.reader(results_file.readlines()))

but this doesn't work 但这不起作用

results_data = list(csv.reader(results_file))

using Python 3.4. 使用Python 3.4。

It seems counter to the documented interface of csv.reader so maybe an expert can elaborate on why. 这似乎与csv.reader的文档化界面csv.reader所以也许专家可以详细说明原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM