I changed a call to bar
which returned synchronously to returning a Future. When the method of bar
actually gets executed it raises an ValueError
.
The unit tests actually ensured that.
Now changing
self.assertRaises(ValueError, foo.bar("/my/invalid/path"))
to
self.assertRaises(ValueError, fut.result())
no longer is a valid assert for some reason.
The whole new code is:
fut = foo.bar("/my/invalid/path")
self.assertIsNotNone(fut)
self.assertRaises(ValueError, fut.result())
The stack trace then is:
"test.py", line 25, in test_load_invalid_res
self.assertRaises(ValueError, fut.result())
File "/usr/lib/python3.5/concurrent/futures/_base.py", line 398, in result
return self.__get_result()
File "/usr/lib/python3.5/concurrent/futures/_base.py", line 357, in __get_result
raise self._exception
File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
result = self.fn(*self.args, **self.kwargs)
ValueError: Could not find resource in resource path: /my/invalid/path
But the stack trace is actually telling me that there was a ValueError
!? Why is it propagading beyond assertRaises
?
EDIT:
The following code does not work:
try:
fut.result()
except ValueError as e:
pass
What works is e.g.:
try:
fut.result()
except Exception as e:
self.assertIsInstance(e, ValueError)
You are calling the method and passing the result to
assertRaises
. Since the error happens before assertRaises is invoked, it will not catch the exception.assertRaises
takes a callable which it calls itself within a try/except. Your code should be:without the calling parens. Alternatively you can use it as a context manager: