diff options
author | wookie184 <wookie1840@gmail.com> | 2024-01-04 19:11:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-04 19:11:34 (GMT) |
commit | 1600d78e2d090319930c6538b496ffcca120a696 (patch) | |
tree | 2c3b626e673d9fc2ccd95df497d792a0241663fe | |
parent | 1ae7ceba29771baf8f2e8d2d4c50a0355cb6b5c8 (diff) | |
download | cpython-1600d78e2d090319930c6538b496ffcca120a696.zip cpython-1600d78e2d090319930c6538b496ffcca120a696.tar.gz cpython-1600d78e2d090319930c6538b496ffcca120a696.tar.bz2 |
gh-113569: Display calls in Mock.assert_has_calls failure when empty (GH-113573)
-rw-r--r-- | Lib/test/test_unittest/testmock/testmock.py | 36 | ||||
-rw-r--r-- | Lib/unittest/mock.py | 8 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2023-12-29-17-57-45.gh-issue-113569.qcRCEI.rst | 2 |
3 files changed, 28 insertions, 18 deletions
diff --git a/Lib/test/test_unittest/testmock/testmock.py b/Lib/test/test_unittest/testmock/testmock.py index 6af8acc..1725406 100644 --- a/Lib/test/test_unittest/testmock/testmock.py +++ b/Lib/test/test_unittest/testmock/testmock.py @@ -1547,25 +1547,33 @@ class MockTest(unittest.TestCase): mock = Mock(spec=f) mock(1) - with self.assertRaisesRegex( - AssertionError, - '^{}$'.format( - re.escape('Calls not found.\n' - 'Expected: [call()]\n' - ' Actual: [call(1)]'))) as cm: + with self.assertRaises(AssertionError) as cm: mock.assert_has_calls([call()]) + self.assertEqual(str(cm.exception), + 'Calls not found.\n' + 'Expected: [call()]\n' + ' Actual: [call(1)]' + ) self.assertIsNone(cm.exception.__cause__) + uncalled_mock = Mock() + with self.assertRaises(AssertionError) as cm: + uncalled_mock.assert_has_calls([call()]) + self.assertEqual(str(cm.exception), + 'Calls not found.\n' + 'Expected: [call()]\n' + ' Actual: []' + ) + self.assertIsNone(cm.exception.__cause__) - with self.assertRaisesRegex( - AssertionError, - '^{}$'.format( - re.escape( - 'Error processing expected calls.\n' - "Errors: [None, TypeError('too many positional arguments')]\n" - "Expected: [call(), call(1, 2)]\n" - ' Actual: [call(1)]'))) as cm: + with self.assertRaises(AssertionError) as cm: mock.assert_has_calls([call(), call(1, 2)]) + self.assertEqual(str(cm.exception), + 'Error processing expected calls.\n' + "Errors: [None, TypeError('too many positional arguments')]\n" + 'Expected: [call(), call(1, 2)]\n' + ' Actual: [call(1)]' + ) self.assertIsInstance(cm.exception.__cause__, TypeError) def test_assert_any_call(self): diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 2adb3d7..93f4d97 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1010,8 +1010,8 @@ class NonCallableMock(Base): for e in expected]) raise AssertionError( f'{problem}\n' - f'Expected: {_CallList(calls)}' - f'{self._calls_repr(prefix=" Actual").rstrip(".")}' + f'Expected: {_CallList(calls)}\n' + f' Actual: {safe_repr(self.mock_calls)}' ) from cause return @@ -1085,7 +1085,7 @@ class NonCallableMock(Base): return klass(**kw) - def _calls_repr(self, prefix="Calls"): + def _calls_repr(self): """Renders self.mock_calls as a string. Example: "\nCalls: [call(1), call(2)]." @@ -1095,7 +1095,7 @@ class NonCallableMock(Base): """ if not self.mock_calls: return "" - return f"\n{prefix}: {safe_repr(self.mock_calls)}." + return f"\nCalls: {safe_repr(self.mock_calls)}." # Denylist for forbidden attribute names in safe mode diff --git a/Misc/NEWS.d/next/Library/2023-12-29-17-57-45.gh-issue-113569.qcRCEI.rst b/Misc/NEWS.d/next/Library/2023-12-29-17-57-45.gh-issue-113569.qcRCEI.rst new file mode 100644 index 0000000..9b63fc9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-29-17-57-45.gh-issue-113569.qcRCEI.rst @@ -0,0 +1,2 @@ +Indicate if there were no actual calls in unittest +:meth:`~unittest.mock.Mock.assert_has_calls` failure. |