Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock CSV DictReader

Is there a way to mock the DictReader for unit testing without actually having to write a file and then re-open it.

My functions accept a DictReader instance, so I could just easily pass them one to test their functionality, but cannot seem to get one without opening a file.

Currently I am manually writing a CSV file and then deleting it each test.

class TestRowsStuff(unittest.TestCase):
    def write_csv(self, path, iterable):
        with open(path, 'wb') as f:
            writer = csv.DictWriter(f, [PP, SN, TN])
            writer.writeheader()
            writer.writerows(iterable)

    def setUp(self):
        ...
        self.test_file = os.path.join('test.csv')
        self.write_csv(self.test_file, test_values)

    def tearDown(self):
        os.remove(self.test_file)
like image 800
Jared Mackey Avatar asked Oct 18 '25 23:10

Jared Mackey


1 Answers

You may use in-memory StringIO object to store/read the Unicode/strings:

In [10]: from StringIO import StringIO

In [11]: import csv

In [12]: csvfile = StringIO()

In [13]: csvfile.seek(0)

# sample taken from [here](https://docs.python.org/2/library/csv.html)    
In [14]: fieldnames = ['first_name', 'last_name']

In [15]: writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

In [16]: writer.writeheader()

In [17]: writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})

In [18]: writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})

In [19]: writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})

In [20]: csvfile.seek(0)

To read it back:

In [21]: csvfile.readlines()
Out[21]: 
['first_name,last_name\r\n',
 'Baked,Beans\r\n',
 'Lovely,Spam\r\n',
 'Wonderful,Spam\r\n']

If you want to use in-memory buffer instead you may also use io.StringIO.

like image 158
Anzel Avatar answered Oct 20 '25 12:10

Anzel