mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-118912: Remove description of issue fixed in 3.5 from autospeccing guide (#119232)
* Remove description of issue fixed in 3.5 from autospeccing guide * Make autospeccing note text more succint and lint whitespace * Add linting changes (missed in last commit) --------- Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
This commit is contained in:
parent
a443e54281
commit
7e57640c7e
1 changed files with 8 additions and 32 deletions
|
@ -2584,40 +2584,16 @@ called incorrectly.
|
|||
|
||||
Before I explain how auto-speccing works, here's why it is needed.
|
||||
|
||||
:class:`Mock` is a very powerful and flexible object, but it suffers from two flaws
|
||||
when used to mock out objects from a system under test. One of these flaws is
|
||||
specific to the :class:`Mock` api and the other is a more general problem with using
|
||||
mock objects.
|
||||
:class:`Mock` is a very powerful and flexible object, but it suffers from a flaw which
|
||||
is general to mocking. If you refactor some of your code, rename members and so on, any
|
||||
tests for code that is still using the *old api* but uses mocks instead of the real
|
||||
objects will still pass. This means your tests can all pass even though your code is
|
||||
broken.
|
||||
|
||||
First the problem specific to :class:`Mock`. :class:`Mock` has two assert methods that are
|
||||
extremely handy: :meth:`~Mock.assert_called_with` and
|
||||
:meth:`~Mock.assert_called_once_with`.
|
||||
.. versionchanged:: 3.5
|
||||
|
||||
>>> mock = Mock(name='Thing', return_value=None)
|
||||
>>> mock(1, 2, 3)
|
||||
>>> mock.assert_called_once_with(1, 2, 3)
|
||||
>>> mock(1, 2, 3)
|
||||
>>> mock.assert_called_once_with(1, 2, 3)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: Expected 'mock' to be called once. Called 2 times.
|
||||
|
||||
Because mocks auto-create attributes on demand, and allow you to call them
|
||||
with arbitrary arguments, if you misspell one of these assert methods then
|
||||
your assertion is gone:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> mock = Mock(name='Thing', return_value=None)
|
||||
>>> mock(1, 2, 3)
|
||||
>>> mock.assret_called_once_with(4, 5, 6) # Intentional typo!
|
||||
|
||||
Your tests can pass silently and incorrectly because of the typo.
|
||||
|
||||
The second issue is more general to mocking. If you refactor some of your
|
||||
code, rename members and so on, any tests for code that is still using the
|
||||
*old api* but uses mocks instead of the real objects will still pass. This
|
||||
means your tests can all pass even though your code is broken.
|
||||
Before 3.5, tests with a typo in the word assert would silently pass when they should
|
||||
raise an error. You can still achieve this behavior by passing ``unsafe=True`` to Mock.
|
||||
|
||||
Note that this is another reason why you need integration tests as well as
|
||||
unit tests. Testing everything in isolation is all fine and dandy, but if you
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue