所以我正在为这个课程编写一个测试(编辑得更清楚):
class SpreadSheet(object):
'''awesome docstring'''
def __init__(self, filename):
self.filename = filename
self.table = []
self.headers = []
with open(self.filename) as csvfile:
filereader = reader(csvfile, delimiter=',')
for row in filereader:
self.table.append(row)
def create_headers(self, populations):
...code...
def lookup_header(self, ltr):
...code...
def write_header(self, targetfile):
...code...
到目前为止看起来像这样:
class TestSpreadSheet(unittest.TestCase):
@contextmanager
def make_fake_csv(self, data):
self.fake_namefile = tempfile.NamedTemporaryFile(delete=False)
with open(self.fake_namefile, 'w') as fake_csv:
fake_writer = csv.writer(fake_csv)
fake_writer.writerows(data)
yield self.fake_namefile.name
os.unlink(self.fake_namefile.name)
def setUp(self):
self.headers = []
self.table = [
['Col1', 'Col2', 'Col3', 'Col4', 'Col5', 'Col6', 'Col7', 'Col8'],
['val1', 'val2', 'val3', 'val4', 'val5', 'val6', 'val7', 'val8'],
['val1', 'val2', 'val3', 'val4', 'val5', 'val6', 'val7', 'val8'],
['val1', 'val2', 'val3', 'val4', 'val5', 'val6', 'val7', 'val8']]
def test___init__(self):
with self.make_fake_csv(self.table) as temp_csv:
spread_sheet = SpreadSheet(temp_csv)
self.assertEqual(
self.table, spread_sheet.table)
...tests for other functions...
我收到了这个错误:
in make_fake_csv
with open(self.fake_namefile, 'w') as fake_csv:
TypeError: coercing to Unicode: need string or buffer, instance found
我已经搜索过许多其他类似的主题,指出使用tempfile
创建一个命名对象或者可以使用with open...
实际调用的东西。虽然我确实得到了它的工作,我的问题是当我尝试使用csv
包格式化我的self.table
为我格式化为csv格式的原始“字符串”(就像一个原始输入换句话说,csv文件)。
有关如何以不同方式测试或使当前代码有效的任何指示?我再次尝试:
弄清楚如何使用csv
来完成所有格式繁重工作以从我的self.table
加载伪造的csv文件,这样我就不必制作一个巨大的字符串格式化表达
运行测试时,请确保假文件与我原始班级with open
中使用的SpreadSheet
一起使用
可以进一步用于运行其他函数的测试,因为它们也需要用文件实例化SpreadSheet
才能执行它们的功能。
作为一个附带问题,制作一个虚假的“内存”文件来做这样的事情(这是我正在尝试上面的内容)或者只是简单地制作一个实际的临时文件是“更精简”磁盘并在测试期间加载它并使用tearDown()
函数将其删除?
答案 0 :(得分:7)
self.fake_namefile
是NamedTemporaryFile
的实例。当您执行open()
调用时,您需要传递包含文件名的字符串,而不是NamedTemporaryFile
实例。 name
变量中提供了临时文件的名称。
with open(self.fake_namefile.name, 'w') as fake_csv:
以下是一些建议:
StringIO
实例进行测试。NamedTemporaryFile
,我建议您直接将其用作上下文管理器,如其他答案中所述。delete=True
选项NamedTemporaryFile
。而是将整个测试包装在上下文管理器中,如下所示。def test_stuff(self):
with tempfile.NamedTemporaryFile() as temp_csv:
self.write_csv_test_data(temp_csv) # Create this to write to temp_csv file object.
temp_csv.flush()
temp_csv.seek(0)
spread_sheet = SpreadSheet(temp_csv.name)
# spread_sheet = SpreadSheet(temp_csv) Use this if Spreadsheet takes a file-like object
...
<强>更新强>
以下是仅使用类似文件的对象的示例,不涉及磁盘文件。
class SpreadSheet(object):
'''awesome docstring'''
def __init__(self, fileobj):
self.table = []
self.headers = []
filereader = reader(fileobj, delimiter=',')
for row in filereader:
self.table.append(row)
...
假设您正在读取磁盘文件,则可以像这样使用它:
with open(path) as csv_file:
spreadsheet = Spreadsheet(csv_file)
....
在测试期间,您可以使用StringIO模块来模拟磁盘上的文件。然后测试完全在内存中运行,因此非常快。
import StringIO
class TestSpreadSheet(unittest.TestCase):
def make_fake_csv(self, data):
"""Return a populdated fake csv file object for testing."""
fake_csv = StringIO.StringIO()
fake_writer = csv.writer(fake_csv)
fake_writer.writerows(data)
fake_csv.seek(0)
return fake_csv
....
def test___init__(self):
temp_csv = self.make_fake_csv(self.table)
spread_sheet = SpreadSheet(temp_csv)
self.assertEqual(
self.table, spread_sheet.table)
答案 1 :(得分:1)
NamedTemporaryFile
返回一个已打开的类文件对象,可以在with
语句中使用,无需调用open
:
self.fake_namefile = tempfile.NamedTemporaryFile(delete=False)
with self.fake_namefile as fake_csv: