如何让python unittest测试一个函数返回一个csv.reader对象?

时间:2016-07-15 01:14:13

标签: python unit-testing csv tdd

我正在使用python 2.7并深入研究TDD。我正在尝试测试一个使用csv模块并返回csv.reader对象的简单函数。我想测试使用assertIsInstance测试返回正确类型的对象,但是我无法弄清楚如何使其工作。

#!/usr/bin/python
import os, csv

def importCSV(fileName):
  '''importCSV brings in the CSV transaction file to be analyzed'''
  try:
    if not(os.path.exists("data")):
      os.makedirs("data") 
  except(IOError):
    return "Couldn't create data directory!"
  try:
    fileFullName = os.path.join("data", fileName)
    return csv.reader(file(fileFullName))
  except(IOError):
    return "File not found!"

目前测试看起来像......

#!/usr/bin/python
from finaImport import finaImport 
import unittest, os, csv

class testImport(unittest.TestCase):
  '''Tests for importing a CSV file'''

  def testImportCSV(self):
    ''' Test a good file and make sure importCSV returns a csv reader object     '''
    readerObject = finaImport.importCSV("toe")
    self.assertTrue(str(type(readerObject))), "_csv.reader")

我真的不认为在str和type函数中包装“toe”是正确的。当我尝试类似的事情时......

self.assertIsInstance(finaImport.importCSV("toe"), csv.reader)

它返回错误,如...

TypeError:  isinstance() arg2 must be a class, type, or tuple of classes and types

帮助???

1 个答案:

答案 0 :(得分:1)

self.assertTrue(str(type(readerObject)), "_csv.reader")

我不认为你的第一次测试(上图)是如此糟糕(我在那里修了一个小错字;你有一个额外的右括号)。它检查类型名称是否正好" _csv.reader"。另一方面," _csv"中的下划线告诉您该对象是csv模块的内部对象。一般来说,你不应该担心这一点。

您对assertIsInstance测试的尝试存在缺陷,因为csv.reader是一个函数对象。如果你在REPL中尝试它,你会看到:

 >>> import csv
 >>> csv.reader
 <built-in function reader>

通常,我们不太关心对象的类型,而是更关心它是否实现某个接口。在这种情况下,csv.reader的帮助说:

>>> help(csv.reader)
  

...返回的对象是一个迭代器。 ...

所以,你可以做以下测试(相反或者除了你的另一个测试):

self.assertIsInstance(readerObject, collections.Iterator)

当然,你需要一个import collections。而且,您可能希望测试迭代器返回字符串列表或类似的东西。那将允许你稍后使用其他东西,测试仍然会通过。