Reputation: 7176
I have a code like this:
def extract(data):
if len(data) == 3:
a = 3
else:
component = data.split("-")
if len(component) == 3:
a,b,c = component
else:
raise globals.myException("data1", "Incorrect format", data)
return a,b,c
This is a simplified one. I want to mock the exception class globals.myException. I'm doing that:
def test_extract_data_throws_exception(self):
with patch('globals.myException') as mock:
mock.__init__("data1", "Incorrect format", "")
with self.assertRaises(myException):
self.assertEqual(extract(""), (""))
And I always get the error: "TypeError: exceptions must be old-style classes or derived from BaseException, not MagicMock"
EDIT: As @Aaron Digulla suggest, monkey patching is the correct solution. I post the solution to help others.
def test_extract_data_throws_exception(self):
#monkey patching
class ReplaceClass(myException):
def __init__(self, module, message, detail = u''):
pass
globals.myException = ReplaceClass
with self.assertRaises(myException:
self.assertEqual(extract(""), (""))
Upvotes: 4
Views: 4118
Reputation: 328594
The reason is raise
checks the type of the argument. It must be a string (a.k.a "old style exceptions") or derived from BaseException
Since a mock isn't either, raise
refuses to use it.
In this specific case, you either have to raise the exception or use monkey patching (= overwrite the symbol globals.myException
in your test and restore it afterwards).
Upvotes: 4