The class presented in this recipe is useful when you are writing module self-tests and need to assert that a fragment of code throws a particular exception.
| Python |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | class expected:
def __init__(self, e):
if isinstance(e, Exception):
self._t, self._v = e.__class__, str(e)
elif isinstance(e, type):
self._t, self._v = e, ""
else:
raise Exception("usage: with expected(Exception): ... or "
"with expected(Exception(\"text\")): ...")
def __enter__(self):
try:
pass
except:
pass # this is a Python 3000 way of saying sys.exc_clear()
def __exit__(self, t, v, tb):
assert t is not None, "expected {0:s} to have been thrown".format(self._t.__name__)
return t is self._t and str(v).startswith(self._v)
if __name__ == "__main__": # some examples
with expected(ZeroDivisionError):
1 / 0
with expected(AssertionError("expected ZeroDivisionError to have been thrown")):
with expected(ZeroDivisionError):
1 / 2
with expected(Exception("foo")):
raise Exception("foo")
with expected(Exception("bar")):
with expected(Exception("foo")): # this won't catch it
raise Exception("bar")
assert False, "should not see me"
with expected(Exception("can specify")):
raise Exception("can specify prefixes")
|
Discussion
I previously had to write something like
<pre> try: ... tested code ... except SomeException, e: assert str(e).startswith("expected error") else: assert False, "should have thrown" </pre> which was really cumbersome. Now I simply do <pre> with expected(SomeException("expected error")): ... tested code ... </pre>


Sign in to comment