Reputation: 12417
Given this code:
try:
#do something
except IOError as message:
logging.error(message)
raise message
I want to test the exception handling part in order to have full coverage. In the unittest I've tried with:
with patch(new=Mock(side_effect=IOError(errno.EIO))):
self.assertRaises(IOError)
but it doesnt work. Is this approach correct?
Upvotes: 3
Views: 3350
Reputation: 4818
Actually you need to start the Mock so that the side_effect
starts, for example the following:
class Test(unittest.TestCase):
def test(self):
mock = m.Mock()
mock.side_effect = Exception("Big badaboum")
self.assertRaises(Exception, mock)
self.assertRaises
can take a callable as second argument, making it equivalent to:
class Test(unittest.TestCase):
def test(self):
mock = m.Mock()
mock.side_effect = Exception("Big badaboum")
with self.assertRaises(Exception):
mock()
And if you want to use it in a test with patch, you can do the following:
import unittest.mock as m
import unittest
def raise_error():
try:
print("Hello") #placeholder for the try clause
except Exception as e:
print(e) #placeholder for the exceptclause
class Test(unittest.TestCase):
@m.patch("__main__.raise_error", side_effect=Exception("Big badaboum")) #replace __main__ by the name of the module with your function
def test(self, mock):
with self.assertRaises(Exception):
mock()
unittest.main()
Edit: And to test the raise of an error inside an except block you need to mock a function call inside the try block you wrote, for instance:
import unittest.mock as m
import unittest
def do_sthing():
print("Hello")
def raise_error():
try:
do_sthing() #this call can be mocked to raise an IOError
except IOError as e:
print(e.strerror)
raise ValueError("Another one")
class Test(unittest.TestCase):
def test(self):
with m.patch("__main__.do_sthing", side_effect=IOError("IOError")):
self.assertRaises(ValueError, raise_error)
unittest.main()
You can use the decorator syntax as well (just putting the test above rewritten to spare some CPU cycle):
class Test(unittest.TestCase):
@m.patch("__main__.do_sthing",side_effect=IOError("IOError"))
def test(self, mock):
self.assertRaises(ValueError, raise_error)
Upvotes: 2