HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Testing file IO errors in python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
errorsfiletestingpython

Problem

Below is a simple class with two methods: the first calls open() to read in a file. The second calls the first method and does error handling.

There is also a corresponding test class that tests the first methods returns data as expected and the other methods test the error handling of potential exceptions thrown by open.

Firstly, I would like to know if these tests are written in the appropriate manner using python3, mocking and patching as I am new to the language and especially to testing.

I also have a query to why mocking an exception to be thrown cannot be handled like the rest of the tests (see last test method)

fileMethods.py

# -*- coding: utf-8 -*-

def readconfig(myfile):
    try:
        filecontent = readfile(myfile)
        #   manipulation of filecontent
    except FileNotFoundError:
        filecontent = "FileNotFoundError"
    except PermissionError:
        filecontent = "PermissionError"
    return filecontent

def readfile(myfile):
    with open(myfile, 'r') as file:
        filecontent = file.read()
    file.close()
    return filecontent


fileMethods_test.py

```
# -- coding: utf-8 --

import io
import unittest
import unittest.mock as mock
import packageName.fileMethods

class TestIO(unittest.TestCase):

def test_readfile_returns_string(self):
mock_file_content = io.StringIO('Content in file')
with mock.patch('packageName.fileMethods.open', return_value=mock_file_content, create=True):
result = packageName.fileMethods.readfile('file_to_readin')
self.assertEqual('Content in file', result)

def test_readconfig_returns_content(self):
with mock.patch('packageName.fileMethods.readfile', return_value="string", create=True):
result = packageName.fileMethods.readconfig('file_to_readin')
self.assertEqual('string', result)

def test_readconfig_handles_FileNotFoundError(self):
with mock.patch('packageName.fileMethods.readfile', side_effect=FileNotFoundEr

Solution

The design of the readconfig() function is seriously problematic. It makes no sense to convert caught exceptions into data, as if the file literally contained the string "FileNotFoundError" or "PermissionError". If you don't have a good way to handle an exception, the right thing to do is let it propagate.

The readfile() function should be simpler:

def read_file(path):
    with open(path) as file:
        return file.read()


To note:

  • Since "read file" is two words in English, it should not be written as a compound word.



  • myfile could be better named. It's a filesystem path, not a file handle. Also, who is "me" in this case?



  • The 'r' mode is the default.



  • You don't need to call file.close() on an already closed file. The whole point of the with block is that the file is automatically closed when exiting the block.

Code Snippets

def read_file(path):
    with open(path) as file:
        return file.read()

Context

StackExchange Code Review Q#136574, answer score: 3

Revisions (0)

No revisions yet.