patternpythonMinor
Testing file IO errors in python
Viewed 0 times
errorsfiletestingpython
Problem
Below is a simple class with two methods: the first calls
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
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
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
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 filecontentfileMethods_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
The
To note:
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.
myfilecould 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 thewithblock 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.