【问题标题】:Why is my assertion failing when reading a NamedTemporaryFile?为什么读取 NamedTemporaryFile 时我的断言失败?
【发布时间】:2016-06-10 13:33:37
【问题描述】:

我正在编写读取文件并根据该文件的内容创建字典的代码。代码非常简单,但我想测试边缘情况。

这是我的尝试:

from tempfile import NamedTemporaryFile
from nose.tools import *

def read_file(filename):
    with open(filename) as f:
        my_dict = { dict(line.strip().split(',')) for line in f }
    return my_dict

def test_read_file():
    file_contents = b"""Hello,World"""
    with NamedTemporaryFile() as fp:
        fp.write(file_contents)
        my_dict = read_file(fp.name)
    print(my_dict)
    assert my_dict == { "Hello" : "World" }

很遗憾,这个断言失败了,因为my_dict 是一个空字典。

我的理解是,一旦NamedTemporaryFile 被关闭,它就会被销毁,所以我不希望它在read_filemy_dict 填充后直接 被销毁。 fp 被打开了两次:一次写一次读——这是麻烦制造者吗?

这是测试读取文件的函数的正确方法吗?如果是这样,为什么我的断言失败了?如果不是,那么编写此测试的更好机制是什么?

【问题讨论】:

  • 您可能需要调用fp.flush() 以确保在您尝试读取之前将数据实际写入文件。
  • @chepner 呃,就是这样。如果您想添加答案,我会接受。不过,这几乎可以肯定是一个骗局。

标签: python unit-testing python-3.x nose temporary-files


【解决方案1】:

您需要刷新写入以确保在读取之前写入数据。

def test_read_file():
    file_contents = b"""Hello,World"""
    with NamedTemporaryFile() as fp:
        fp.write(file_contents)
        fp.flush()
        my_dict = read_file(fp.name)
    print(my_dict)
    assert my_dict == { "Hello" : "World" }

【讨论】:

  • 接受这个,因为它回答了为什么的问题,但赞成另一个答案,因为它是一个更好的方法。
【解决方案2】:

您可以使用内存中类似文件的对象,而不是使用真实文件。这需要模拟 open,或者更改您的 API 以采用类似文件的对象而不是文件名。

import unittest.mock
import io

def test_read_file():
    file_contents = io.BytesIO(b"""Hello,World""")
    m = unittest.mock.mock_open(read_data=file_contents)
    with unittest.mock.patch('__main__.open', m):
        my_dict = read_file("fake.txt")
    print(my_dict)
    assert my_dict == { "Hello" : "World" }

【讨论】:

  • unittest 包含一些非常疯狂的东西!不过,我喜欢内存中对象的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 2014-10-26
  • 1970-01-01
  • 2019-01-19
  • 2013-09-06
  • 2020-12-30
相关资源
最近更新 更多