unittest of file-reading function

H

Helge Stenstroem

Say I have a function

def f(filename):
result = openFileAndProcessContents(filename)
return result

Can that function be unit tested without having a real file as input?
Something along the lines of

import unittest
class tests(unittest.TestCase):
def test1(self):
fileContents = "bla bla bla\nmore bla bla bla"
??? # make f read this string instead of opening a file
expected = expectedResult
result = f(filename)
self.assertEqual(result, expected)

One possibility would be to make the unit test write to a temporary
file. Are there better alternatives?
 
P

Peter Hansen

Helge said:
Say I have a function

def f(filename):
result = openFileAndProcessContents(filename)
return result

Can that function be unit tested without having a real file as input?
Something along the lines of

import unittest
class tests(unittest.TestCase):
def test1(self):
fileContents = "bla bla bla\nmore bla bla bla"
??? # make f read this string instead of opening a file
expected = expectedResult
result = f(filename)
self.assertEqual(result, expected)

One possibility would be to make the unit test write to a temporary
file. Are there better alternatives?

The simplest approach is to use a StringIO. Often that will require
passing a "file" object to the routine instead of a file *name*, but
often that's better anyway (decouples file management and parsing).

Another approach is to create a "mock file" object. Depending on your
needs, this can be a very simple or a very complex thing to do. I can
offer more detail/suggestions here if you need.

-Peter
 
K

Kent Johnson

Helge said:
Say I have a function

def f(filename):
result = openFileAndProcessContents(filename)
return result

Can that function be unit tested without having a real file as input?

If you can refactor openFileAndProcessContents() so it looks like this:
def openFileAndProcessContents(filename):
data = open(filename).read()
processContents(data)

then you can write your tests against processContents() and just pass it a string with the test data.

I usually have a set of test files as part of my project that I can pass to functions like this.

Kent
 
S

shafran

Hi!

You can use tempfile.mktemp(), then write test contents to this temp
file,
pass it to your function, unlink tempfile.

you can create / unlink temp file in setUp() / tearDown() methods.

Alexander.
 
G

Guest

* Helge Stenstroem said:
Say I have a function

def f(filename):
result = openFileAndProcessContents(filename)
return result

Can that function be unit tested without having a real file as input?
Something along the lines of

import unittest
class tests(unittest.TestCase):
def test1(self):
fileContents = "bla bla bla\nmore bla bla bla"
??? # make f read this string instead of opening a file
expected = expectedResult
result = f(filename)
self.assertEqual(result, expected)

One possibility would be to make the unit test write to a temporary
file. Are there better alternatives?

You can also just replace or shadow the file/open builtin (that's what I'm
doing). Something like:

def test1(self):
import StringIO

fileContents = "bla bla bla\nmore bla bla bla"

def myfile(name, mode, buffering):
return StringIO.StringIO(fileContents)
testedmodule.file = myfile
try:
expected = expectedResult
result = f(filename)
finally:
del testedmodule.file

self.assertEqual(result, expected)

(if you're using open, replace .file with .open)
(testedmodule is of course the module where the file call happens)

nd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,269
Messages
2,571,348
Members
48,026
Latest member
ArnulfoCat

Latest Threads

Top