diff options
-rw-r--r-- | Lib/unittest/mock.py | 36 | ||||
-rw-r--r-- | Lib/unittest/test/testmock/testmock.py | 30 | ||||
-rw-r--r-- | Misc/ACKS | 1 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2018-10-25-09-59-00.bpo-35047.abbaa.rst | 3 |
4 files changed, 62 insertions, 8 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 1a6c1a6..1977b87 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -30,6 +30,7 @@ import pprint import sys import builtins from types import ModuleType +from unittest.util import safe_repr from functools import wraps, partial @@ -778,8 +779,10 @@ class NonCallableMock(Base): """ self = _mock_self if self.call_count != 0: - msg = ("Expected '%s' to not have been called. Called %s times." % - (self._mock_name or 'mock', self.call_count)) + msg = ("Expected '%s' to not have been called. Called %s times.%s" + % (self._mock_name or 'mock', + self.call_count, + self._calls_repr())) raise AssertionError(msg) def assert_called(_mock_self): @@ -796,8 +799,10 @@ class NonCallableMock(Base): """ self = _mock_self if not self.call_count == 1: - msg = ("Expected '%s' to have been called once. Called %s times." % - (self._mock_name or 'mock', self.call_count)) + msg = ("Expected '%s' to have been called once. Called %s times.%s" + % (self._mock_name or 'mock', + self.call_count, + self._calls_repr())) raise AssertionError(msg) def assert_called_with(_mock_self, *args, **kwargs): @@ -825,8 +830,10 @@ class NonCallableMock(Base): with the specified arguments.""" self = _mock_self if not self.call_count == 1: - msg = ("Expected '%s' to be called once. Called %s times." % - (self._mock_name or 'mock', self.call_count)) + msg = ("Expected '%s' to be called once. Called %s times.%s" + % (self._mock_name or 'mock', + self.call_count, + self._calls_repr())) raise AssertionError(msg) return self.assert_called_with(*args, **kwargs) @@ -847,8 +854,8 @@ class NonCallableMock(Base): if not any_order: if expected not in all_calls: raise AssertionError( - 'Calls not found.\nExpected: %r\n' - 'Actual: %r' % (_CallList(calls), self.mock_calls) + 'Calls not found.\nExpected: %r%s' + % (_CallList(calls), self._calls_repr(prefix="Actual")) ) from cause return @@ -909,6 +916,19 @@ class NonCallableMock(Base): return klass(**kw) + def _calls_repr(self, prefix="Calls"): + """Renders self.mock_calls as a string. + + Example: "\nCalls: [call(1), call(2)]." + + If self.mock_calls is empty, an empty string is returned. The + output will be truncated if very long. + """ + if not self.mock_calls: + return "" + return f"\n{prefix}: {safe_repr(self.mock_calls)}." + + def _try_iter(obj): if obj is None: diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index c7bfa27..8cd284a 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -1,4 +1,5 @@ import copy +import re import sys import tempfile @@ -407,6 +408,14 @@ class MockTest(unittest.TestCase): lambda: mock.assert_called_once_with('bob', 'bar', baz=2) ) + def test_assert_called_once_with_call_list(self): + m = Mock() + m(1) + m(2) + self.assertRaisesRegex(AssertionError, + re.escape("Calls: [call(1), call(2)]"), + lambda: m.assert_called_once_with(2)) + def test_assert_called_once_with_function_spec(self): def f(a, b, c, d=None): @@ -1250,6 +1259,13 @@ class MockTest(unittest.TestCase): with self.assertRaises(AssertionError): m.hello.assert_not_called() + def test_assert_not_called_message(self): + m = Mock() + m(1, 2) + self.assertRaisesRegex(AssertionError, + re.escape("Calls: [call(1, 2)]"), + m.assert_not_called) + def test_assert_called(self): m = Mock() with self.assertRaises(AssertionError): @@ -1271,6 +1287,20 @@ class MockTest(unittest.TestCase): with self.assertRaises(AssertionError): m.hello.assert_called_once() + def test_assert_called_once_message(self): + m = Mock() + m(1, 2) + m(3) + self.assertRaisesRegex(AssertionError, + re.escape("Calls: [call(1, 2), call(3)]"), + m.assert_called_once) + + def test_assert_called_once_message_not_called(self): + m = Mock() + with self.assertRaises(AssertionError) as e: + m.assert_called_once() + self.assertNotIn("Calls:", str(e.exception)) + #Issue21256 printout of keyword args should be in deterministic order def test_sorted_call_signature(self): m = Mock() @@ -1570,6 +1570,7 @@ Daniel Stokes Michael Stone Serhiy Storchaka Ken Stox +Petter Strandmark Charalampos Stratakis Dan Stromberg Donald Stufft diff --git a/Misc/NEWS.d/next/Library/2018-10-25-09-59-00.bpo-35047.abbaa.rst b/Misc/NEWS.d/next/Library/2018-10-25-09-59-00.bpo-35047.abbaa.rst new file mode 100644 index 0000000..12eda27 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-10-25-09-59-00.bpo-35047.abbaa.rst @@ -0,0 +1,3 @@ +``unittest.mock`` now includes mock calls in exception messages if +``assert_not_called``, ``assert_called_once``, or ``assert_called_once_with`` +fails. Patch by Petter Strandmark.
\ No newline at end of file |