This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2012年07月11日 03:19 by Brian.Jones, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| mock_assert_called_once_with_output_update.patch | Brian.Jones, 2012年07月11日 03:19 | Enhance usefulness of assert_called_once_with failure message. | review | |
| mock_assert_called_once_with_output_update_including_test.patch | Arnav.Khare, 2012年09月28日 15:08 | review | ||
| Messages (8) | |||
|---|---|---|---|
| msg165223 - (view) | Author: Brian Jones (Brian.Jones) * | Date: 2012年07月11日 03:19 | |
In Python 3.3.0b1, if the number of calls to a mock is, say, zero, and you call assert_called_once_with() on that mock, it will throw an exception which says "Expected to be called once. Called 0 times."
This is nice, but it would be nicer if the output message actually told the end user *what* it expected to be called once. I've supplied a patch and documentation update that makes this change by adding _mock_name to the output message using the variable interpolation method already being used in that message to output the call count.
The result looks like this (for the case in the documentation):
Python 3.3.0b1 (default:2ecdda96f970+, Jul 10 2012, 22:45:18)
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from unittest.mock import Mock
[103576 refs]
>>> mock = Mock(return_value=None)
[103641 refs]
>>> mock('foo', bar='baz')
[103679 refs]
>>> mock.assert_called_once_with('foo', bar='baz')
[103680 refs]
>>> mock('foo', bar='baz')
[103703 refs]
>>> mock.assert_called_once_with('foo', bar='baz')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/brianj/Dropbox/Source/Python/cpython/Lib/unittest/mock.py", line 736, in assert_called_once_with
raise AssertionError(msg)
AssertionError: Expected 'mock' to be called once. Called 2 times.
[103758 refs]
In the above case, the mock was never given a name, and wasn't instantiated with any particular target. Here's an example using a patch on 'time.time' to show the effect:
Python 3.3.0b1 (default:2ecdda96f970+, Jul 10 2012, 22:45:18)
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from unittest.mock import patch
[106009 refs]
>>> with patch('time.time') as foo:
... foo.assert_called_once_with()
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/Users/brianj/Dropbox/Source/Python/cpython/Lib/unittest/mock.py", line 736, in assert_called_once_with
raise AssertionError(msg)
AssertionError: Expected 'time' to be called once. Called 0 times.
[106621 refs]
|
|||
| msg165224 - (view) | Author: Chris Jerdonek (chris.jerdonek) * (Python committer) | Date: 2012年07月11日 03:55 | |
I have a minor suggestion. I would suggest--
+ msg = ("Expected %s to be called once. Called %s times." %
+ (repr(self._mock_name) or 'mock', self.call_count))
so that one can distinguish between self._mock_name not being defined and self._mock_name being equal to 'mock'.
|
|||
| msg165239 - (view) | Author: Michael Foord (michael.foord) * (Python committer) | Date: 2012年07月11日 09:02 | |
Looks good, thanks. |
|||
| msg165445 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2012年07月14日 12:48 | |
Nice idea! A small question: Why print 'time' in the message and not 'time.time'? |
|||
| msg171486 - (view) | Author: Arnav Khare (Arnav.Khare) | Date: 2012年09月28日 15:08 | |
Added a test to the patch supplied. |
|||
| msg171487 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2012年09月28日 15:16 | |
New changeset 70d43fedb2d7 by Michael Foord in branch 'default': Closes issue 15323. Improve failure message of Mock.assert_called_once_with http://hg.python.org/cpython/rev/70d43fedb2d7 |
|||
| msg171489 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2012年09月28日 15:21 | |
Cool change. I assume when you use mock.patch as decorator the mock name is set to the mocked object? |
|||
| msg171492 - (view) | Author: Michael Foord (michael.foord) * (Python committer) | Date: 2012年09月28日 15:27 | |
Eric: yes, patch sets the name on the mock objects it creates. A mock only knows its direct name, not its full 'dotted' name (i.e. a mock knows it is called 'time' but not that it is 'time.time'). It is possible (but harder) to deduce that name (follow the chain of parents), so for the moment this change will do. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:32 | admin | set | github: 59528 |
| 2012年09月28日 15:27:32 | michael.foord | set | messages: + msg171492 |
| 2012年09月28日 15:21:20 | eric.araujo | set | messages: + msg171489 |
| 2012年09月28日 15:16:36 | python-dev | set | status: open -> closed nosy: + python-dev messages: + msg171487 resolution: fixed stage: resolved |
| 2012年09月28日 15:08:27 | Arnav.Khare | set | files:
+ mock_assert_called_once_with_output_update_including_test.patch nosy: + Arnav.Khare messages: + msg171486 |
| 2012年07月14日 12:48:17 | eric.araujo | set | nosy:
+ eric.araujo messages: + msg165445 |
| 2012年07月11日 09:02:31 | michael.foord | set | assignee: michael.foord messages: + msg165239 nosy: + michael.foord |
| 2012年07月11日 03:55:18 | chris.jerdonek | set | nosy:
+ chris.jerdonek messages: + msg165224 |
| 2012年07月11日 03:19:21 | Brian.Jones | create | |