Skip to content

Commit f1aea75

Browse files
authored
Merge pull request #1079 from python-cmd2/autospec_doc_updates
Update autospec mock documentation
2 parents 89a5fcf + e4070af commit f1aea75

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

docs/testing.rst

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,45 @@ Mocking
2626
.. _python_mock_patch:
2727
https://docs.python.org/3/library/unittest.mock.html#patch
2828

29-
If you need to mock anything in your cmd2 application, and most specifically in sub-classes of :class:`~cmd2.Cmd` or
30-
:class:`~cmd2.command_definition.CommandSet`, you must use `Autospeccing <python_mock_autospeccing_>`_,
31-
`spec=True <python_mock_patch_>`_, or whatever equivalant is provided in the mocking library you're using.
32-
33-
In order to automatically load functions as commands cmd2 performs a number of reflection calls to look up attributes
34-
of classes defined in your cmd2 application. Many mocking libraries will automatically create mock objects to match any
35-
attribute being requested, regardless of whether they're present in the object being mocked. This behavior can
36-
incorrectly instruct cmd2 to treat a function or attribute as something it needs to recognize and process. To prevent
37-
this, you should always mock with `Autospeccing <python_mock_autospeccing_>`_ or `spec=True <python_mock_patch_>`_
38-
enabled.
39-
40-
Example of spec=True
41-
~~~~~~~~~~~~~~~~~~~~
29+
If you need to mock anything in your cmd2 application, and most specifically in
30+
sub-classes of :class:`~cmd2.Cmd` or
31+
:class:`~cmd2.command_definition.CommandSet`, you must use `Autospeccing
32+
<python_mock_autospeccing_>`_, `spec=True <python_mock_patch_>`_, or whatever
33+
equivalant is provided in the mocking library you're using.
34+
35+
In order to automatically load functions as commands cmd2 performs a number of
36+
reflection calls to look up attributes of classes defined in your cmd2
37+
application. Many mocking libraries will automatically create mock objects to
38+
match any attribute being requested, regardless of whether they're present in
39+
the object being mocked. This behavior can incorrectly instruct cmd2 to treat a
40+
function or attribute as something it needs to recognize and process. To
41+
prevent this, you should always mock with `Autospeccing
42+
<python_mock_autospeccing_>`_ or `spec=True <python_mock_patch_>`_ enabled.
43+
44+
If you don't have autospeccing on, your unit tests will failing with an error
45+
message like::
46+
47+
cmd2.exceptions.CommandSetRegistrationError: Subcommand
48+
<MagicMock name='cmdloop.subcommand_name' id='4506146416'> is not
49+
valid: must be a string. Received <class 'unittest.mock.MagicMock'> instead
50+
51+
52+
Examples
53+
~~~~~~~~
54+
4255
.. code-block:: python
4356
4457
def test_mocked_methods():
4558
with mock.patch.object(MockMethodApp, 'foo', spec=True):
4659
cli = MockMethodApp()
60+
61+
Another one using `pytest-mock <https://pypi.org/project/pytest-mock/>`_ to
62+
provide a ``mocker`` fixture:
63+
64+
.. code-block:: python
65+
66+
def test_mocked_methods2(mocker):
67+
mock_cmdloop = mocker.patch("cmd2.Cmd.cmdloop", autospec=True)
68+
cli = cmd2.Cmd()
69+
cli.cmdloop()
70+
assert mock_cmdloop.call_count == 1

0 commit comments

Comments
 (0)