testtools-dev team mailing list archive
-
testtools-dev team
-
Mailing list archive
-
Message #00962
[Merge] lp:~jml/testtools/assert-raises-lambda into lp:testtools
Jonathan Lange has proposed merging lp:~jml/testtools/assert-raises-lambda into lp:testtools.
Requested reviews:
testtools committers (testtools-committers)
Related bugs:
Bug #881052 in testtools: "assertRaises gives error about a lambda"
https://bugs.launchpad.net/testtools/+bug/881052
For more details, see:
https://code.launchpad.net/~jml/testtools/assert-raises-lambda/+merge/90574
When assertRaises currently fails, it doesn't mention the callable that it was invoked with. Instead it mentions a lambda that we make up in order to be able to re-use the Raises matcher.
This patch addresses this problem by using a wrapper object instead of a lambda. The wrapper object is a nullary callable and has a custom __repr__ method that forwards to the callable that assertRaises was invoked with.
--
https://code.launchpad.net/~jml/testtools/assert-raises-lambda/+merge/90574
Your team testtools developers is subscribed to branch lp:testtools.
=== modified file 'NEWS'
--- NEWS 2012-01-10 17:59:27 +0000
+++ NEWS 2012-01-28 13:49:24 +0000
@@ -21,6 +21,9 @@
previous release promised clean stack, but now we actually provide it.
(Jonathan Lange, #854769)
+* ``assertRaises`` now includes the ``repr`` of the callable that failed to raise
+ properly. (Jonathan Lange, #881052)
+
* Failed equality assertions now line up. (Jonathan Lange, #879339)
* ``MatchesAll`` and ``MatchesListwise`` both take a ``first_only`` keyword
=== modified file 'testtools/testcase.py'
--- testtools/testcase.py 2011-12-05 15:21:33 +0000
+++ testtools/testcase.py 2012-01-28 13:49:24 +0000
@@ -384,8 +384,13 @@
capture = CaptureMatchee()
matcher = Raises(MatchesAll(ReRaiseOtherTypes(),
MatchesException(excClass), capture))
-
- self.assertThat(lambda: callableObj(*args, **kwargs), matcher)
+ class OurCallable(object):
+ """Wrapper around callableObj to ensure good repr."""
+ def __call__(self):
+ return callableObj(*args, **kwargs)
+ def __repr__(self):
+ return repr(callableObj)
+ self.assertThat(OurCallable(), matcher)
return capture.matchee
failUnlessRaises = assertRaises
=== modified file 'testtools/tests/test_testcase.py'
--- testtools/tests/test_testcase.py 2011-10-30 16:27:05 +0000
+++ testtools/tests/test_testcase.py 2012-01-28 13:49:24 +0000
@@ -25,6 +25,7 @@
)
from testtools.matchers import (
Annotate,
+ Contains,
DocTestMatches,
Equals,
MatchesException,
@@ -309,6 +310,17 @@
self.assertFails('<function <lambda> at ...> returned None',
self.assertRaises, expectedExceptions, lambda: None)
+ def test_assertRaises_function_repr_in_exception(self):
+ # When assertRaises fails, it includes the repr of the invoked
+ # function in the error message, so it's easy to locate the problem.
+ def foo():
+ """An arbitrary function."""
+ pass
+ self.assertThat(
+ lambda: self.assertRaises(Exception, foo),
+ Raises(
+ MatchesException(self.failureException, '.*%r.*' % (foo,))))
+
def assertFails(self, message, function, *args, **kwargs):
"""Assert that function raises a failure with the given message."""
failure = self.assertRaises(
Follow ups