【问题标题】:Mock_open CSV file not getting any dataMock_open CSV 文件没有得到任何数据
【发布时间】:2016-06-16 00:36:34
【问题描述】:

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

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

像这样使用 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'))

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

【问题讨论】:

  • 我想这是因为csv实际上是一个_csv.c,一个编译后的c模块,所以看起来mocks没有被结转?

标签: python csv mocking


【解决方案1】:

这是因为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,如文档所述。

【讨论】:

  • 另一种测试 csv.reader(和 csv.DiscReader)的解决方案是在 MagicMock mock_open 返回上实现 __next__() 方法。如此处所示:stackoverflow.com/a/24779923/484127
  • 同意。实现__next__() 是一种整洁的方法。
【解决方案2】:

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

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

这行得通

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

但这不起作用

results_data = list(csv.reader(results_file))

使用 Python 3.4。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多