METADATA 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. Metadata-Version: 2.1
  2. Name: pytest-mock
  3. Version: 2.0.0
  4. Summary: Thin-wrapper around the mock package for easier use with py.test
  5. Home-page: https://github.com/pytest-dev/pytest-mock/
  6. Author: Bruno Oliveira
  7. Author-email: nicoddemus@gmail.com
  8. License: MIT
  9. Keywords: pytest mock
  10. Platform: any
  11. Classifier: Development Status :: 5 - Production/Stable
  12. Classifier: Framework :: Pytest
  13. Classifier: Intended Audience :: Developers
  14. Classifier: License :: OSI Approved :: MIT License
  15. Classifier: Operating System :: OS Independent
  16. Classifier: Programming Language :: Python :: 2
  17. Classifier: Programming Language :: Python :: 2.7
  18. Classifier: Programming Language :: Python :: 3
  19. Classifier: Programming Language :: Python :: 3.4
  20. Classifier: Programming Language :: Python :: 3.5
  21. Classifier: Programming Language :: Python :: 3.6
  22. Classifier: Programming Language :: Python :: 3.7
  23. Classifier: Programming Language :: Python :: 3.8
  24. Classifier: Topic :: Software Development :: Testing
  25. Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
  26. Requires-Dist: pytest (>=2.7)
  27. Requires-Dist: mock ; python_version < "3.0"
  28. Provides-Extra: dev
  29. Requires-Dist: pre-commit ; extra == 'dev'
  30. Requires-Dist: tox ; extra == 'dev'
  31. ===========
  32. pytest-mock
  33. ===========
  34. This plugin provides a ``mocker`` fixture which is a thin-wrapper around the patching API
  35. provided by the `mock package <http://pypi.python.org/pypi/mock>`_:
  36. .. code-block:: python
  37. import os
  38. class UnixFS:
  39. @staticmethod
  40. def rm(filename):
  41. os.remove(filename)
  42. def test_unix_fs(mocker):
  43. mocker.patch('os.remove')
  44. UnixFS.rm('file')
  45. os.remove.assert_called_once_with('file')
  46. Besides undoing the mocking automatically after the end of the test, it also provides other
  47. nice utilities such as ``spy`` and ``stub``, and uses pytest introspection when
  48. comparing calls.
  49. |python| |version| |anaconda| |ci| |coverage| |black|
  50. .. |version| image:: http://img.shields.io/pypi/v/pytest-mock.svg
  51. :target: https://pypi.python.org/pypi/pytest-mock
  52. .. |anaconda| image:: https://img.shields.io/conda/vn/conda-forge/pytest-mock.svg
  53. :target: https://anaconda.org/conda-forge/pytest-mock
  54. .. |ci| image:: https://github.com/pytest-dev/pytest-mock/workflows/build/badge.svg
  55. :target: https://github.com/pytest-dev/pytest-mock/actions
  56. .. |coverage| image:: https://coveralls.io/repos/github/pytest-dev/pytest-mock/badge.svg?branch=master
  57. :target: https://coveralls.io/github/pytest-dev/pytest-mock?branch=master
  58. .. |python| image:: https://img.shields.io/pypi/pyversions/pytest-mock.svg
  59. :target: https://pypi.python.org/pypi/pytest-mock/
  60. .. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
  61. :target: https://github.com/ambv/black
  62. `Professionally supported pytest-mock is now available <https://tidelift.com/subscription/pkg/pypi-pytest_mock?utm_source=pypi-pytest-mock&utm_medium=referral&utm_campaign=readme>`_
  63. Usage
  64. =====
  65. The ``mocker`` fixture has the same API as
  66. `mock.patch <https://docs.python.org/3/library/unittest.mock.html#patch>`_,
  67. supporting the same arguments:
  68. .. code-block:: python
  69. def test_foo(mocker):
  70. # all valid calls
  71. mocker.patch('os.remove')
  72. mocker.patch.object(os, 'listdir', autospec=True)
  73. mocked_isfile = mocker.patch('os.path.isfile')
  74. The supported methods are:
  75. * `mocker.patch <https://docs.python.org/3/library/unittest.mock.html#patch>`_
  76. * `mocker.patch.object <https://docs.python.org/3/library/unittest.mock.html#patch-object>`_
  77. * `mocker.patch.multiple <https://docs.python.org/3/library/unittest.mock.html#patch-multiple>`_
  78. * `mocker.patch.dict <https://docs.python.org/3/library/unittest.mock.html#patch-dict>`_
  79. * `mocker.stopall <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch.stopall>`_
  80. * ``mocker.resetall()``: calls `reset_mock() <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.reset_mock>`_ in all mocked objects up to this point.
  81. Also, as a convenience, these names from the ``mock`` module are accessible directly from ``mocker``:
  82. * `Mock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock>`_
  83. * `MagicMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock>`_
  84. * `PropertyMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock>`_
  85. * `ANY <https://docs.python.org/3/library/unittest.mock.html#any>`_
  86. * `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ *(Version 1.4)*
  87. * `call <https://docs.python.org/3/library/unittest.mock.html#call>`_ *(Version 1.1)*
  88. * `sentinel <https://docs.python.org/3/library/unittest.mock.html#sentinel>`_ *(Version 1.2)*
  89. * `mock_open <https://docs.python.org/3/library/unittest.mock.html#mock-open>`_
  90. Spy
  91. ---
  92. The ``mocker.spy`` object acts exactly like the original method in all cases, except the spy
  93. also tracks method calls, return values and exceptions raised.
  94. .. code-block:: python
  95. def test_spy(mocker):
  96. class Foo(object):
  97. def bar(self, v):
  98. return v * 2
  99. foo = Foo()
  100. spy = mocker.spy(foo, 'bar')
  101. assert foo.bar(21) == 42
  102. spy.assert_called_once_with(21)
  103. assert spy.spy_return == 42
  104. The object returned by ``mocker.spy`` is a ``MagicMock`` object, so all standard checking functions
  105. are available (like ``assert_called_once_with`` in the example above).
  106. In addition, spy objects contain two extra attributes:
  107. * ``spy_return``: contains the returned value of the spied function.
  108. * ``spy_exception``: contain the last exception value raised by the spied function/method when
  109. it was last called, or ``None`` if no exception was raised.
  110. ``mocker.spy`` also works for class and static methods.
  111. .. note::
  112. In versions earlier than ``2.0``, the attributes were called ``return_value`` and
  113. ``side_effect`` respectively, but due to incompatibilities with ``unittest.mock``
  114. they had to be renamed (see `#175`_ for details).
  115. .. _#175: https://github.com/pytest-dev/pytest-mock/issues/175
  116. Stub
  117. ----
  118. The stub is a mock object that accepts any arguments and is useful to test callbacks.
  119. It may receive an optional name that is shown in its ``repr``, useful for debugging.
  120. .. code-block:: python
  121. def test_stub(mocker):
  122. def foo(on_something):
  123. on_something('foo', 'bar')
  124. stub = mocker.stub(name='on_something_stub')
  125. foo(stub)
  126. stub.assert_called_once_with('foo', 'bar')
  127. Improved reporting of mock call assertion errors
  128. ------------------------------------------------
  129. This plugin monkeypatches the mock library to improve pytest output for failures
  130. of mock call assertions like ``Mock.assert_called_with()`` by hiding internal traceback
  131. entries from the ``mock`` module.
  132. It also adds introspection information on differing call arguments when
  133. calling the helper methods. This features catches `AssertionError` raised in
  134. the method, and uses py.test's own `advanced assertions`_ to return a better
  135. diff::
  136. mocker = <pytest_mock.MockFixture object at 0x0381E2D0>
  137. def test(mocker):
  138. m = mocker.Mock()
  139. m('fo')
  140. > m.assert_called_once_with('', bar=4)
  141. E AssertionError: Expected call: mock('', bar=4)
  142. E Actual call: mock('fo')
  143. E
  144. E pytest introspection follows:
  145. E
  146. E Args:
  147. E assert ('fo',) == ('',)
  148. E At index 0 diff: 'fo' != ''
  149. E Use -v to get the full diff
  150. E Kwargs:
  151. E assert {} == {'bar': 4}
  152. E Right contains more items:
  153. E {'bar': 4}
  154. E Use -v to get the full diff
  155. test_foo.py:6: AssertionError
  156. ========================== 1 failed in 0.03 seconds ===========================
  157. This is useful when asserting mock calls with many/nested arguments and trying
  158. to quickly see the difference.
  159. This feature is probably safe, but if you encounter any problems it can be disabled in
  160. your ``pytest.ini`` file:
  161. .. code-block:: ini
  162. [pytest]
  163. mock_traceback_monkeypatch = false
  164. Note that this feature is automatically disabled with the ``--tb=native`` option. The underlying
  165. mechanism used to suppress traceback entries from ``mock`` module does not work with that option
  166. anyway plus it generates confusing messages on Python 3.5 due to exception chaining
  167. .. _advanced assertions: http://pytest.org/latest/assert.html
  168. Use standalone "mock" package
  169. -----------------------------
  170. *New in version 1.4.0.*
  171. Python 3 users might want to use a newest version of the ``mock`` package as published on PyPI
  172. than the one that comes with the Python distribution.
  173. .. code-block:: ini
  174. [pytest]
  175. mock_use_standalone_module = true
  176. This will force the plugin to import ``mock`` instead of the ``unittest.mock`` module bundled with
  177. Python 3.4+. Note that this option is only used in Python 3+, as Python 2 users only have the option
  178. to use the ``mock`` package from PyPI anyway.
  179. Note about usage as context manager
  180. -----------------------------------
  181. Although mocker's API is intentionally the same as ``mock.patch``'s, its use
  182. as context manager and function decorator is **not** supported through the
  183. fixture:
  184. .. code-block:: python
  185. def test_context_manager(mocker):
  186. a = A()
  187. with mocker.patch.object(a, 'doIt', return_value=True, autospec=True): # DO NOT DO THIS
  188. assert a.doIt() == True
  189. The purpose of this plugin is to make the use of context managers and
  190. function decorators for mocking unnecessary.
  191. Requirements
  192. ============
  193. * Python 2.7, Python 3.4+
  194. * pytest
  195. * mock (for Python 2)
  196. Install
  197. =======
  198. Install using `pip <http://pip-installer.org/>`_:
  199. .. code-block:: console
  200. $ pip install pytest-mock
  201. Changelog
  202. =========
  203. Please consult the `changelog page`_.
  204. .. _changelog page: https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst
  205. Why bother with a plugin?
  206. =========================
  207. There are a number of different ``patch`` usages in the standard ``mock`` API,
  208. but IMHO they don't scale very well when you have more than one or two
  209. patches to apply.
  210. It may lead to an excessive nesting of ``with`` statements, breaking the flow
  211. of the test:
  212. .. code-block:: python
  213. import mock
  214. def test_unix_fs():
  215. with mock.patch('os.remove'):
  216. UnixFS.rm('file')
  217. os.remove.assert_called_once_with('file')
  218. with mock.patch('os.listdir'):
  219. assert UnixFS.ls('dir') == expected
  220. # ...
  221. with mock.patch('shutil.copy'):
  222. UnixFS.cp('src', 'dst')
  223. # ...
  224. One can use ``patch`` as a decorator to improve the flow of the test:
  225. .. code-block:: python
  226. @mock.patch('os.remove')
  227. @mock.patch('os.listdir')
  228. @mock.patch('shutil.copy')
  229. def test_unix_fs(mocked_copy, mocked_listdir, mocked_remove):
  230. UnixFS.rm('file')
  231. os.remove.assert_called_once_with('file')
  232. assert UnixFS.ls('dir') == expected
  233. # ...
  234. UnixFS.cp('src', 'dst')
  235. # ...
  236. But this poses a few disadvantages:
  237. - test functions must receive the mock objects as parameter, even if you don't plan to
  238. access them directly; also, order depends on the order of the decorated ``patch``
  239. functions;
  240. - receiving the mocks as parameters doesn't mix nicely with pytest's approach of
  241. naming fixtures as parameters, or ``pytest.mark.parametrize``;
  242. - you can't easily undo the mocking during the test execution;
  243. An alternative is to use ``contextlib.ExitStack`` to stack the context managers in a single level of indentation
  244. to improve the flow of the test:
  245. .. code-block:: python
  246. import contextlib
  247. import mock
  248. def test_unix_fs():
  249. with contextlib.ExitStack() as stack:
  250. stack.enter_context(mock.patch('os.remove'))
  251. UnixFS.rm('file')
  252. os.remove.assert_called_once_with('file')
  253. stack.enter_context(mock.patch('os.listdir'))
  254. assert UnixFS.ls('dir') == expected
  255. # ...
  256. stack.enter_context(mock.patch('shutil.copy'))
  257. UnixFS.cp('src', 'dst')
  258. # ...
  259. But this is arguably a little more complex than using ``pytest-mock``.
  260. Contributing
  261. ============
  262. Contributions are welcome! After cloning the repository, create a virtual env
  263. and install ``pytest-mock`` in editable mode with ``dev`` extras:
  264. .. code-block:: console
  265. $ pip install --editable .[dev]
  266. $ pre-commit install
  267. Tests are run with ``tox``, you can run the baseline environments before submitting a PR:
  268. .. code-block:: console
  269. $ tox -e py27,py36,linting
  270. Style checks and formatting are done automatically during commit courtesy of
  271. `pre-commit <https://pre-commit.com>`_.
  272. License
  273. =======
  274. Distributed under the terms of the `MIT`_ license.
  275. Security contact information
  276. ============================
  277. To report a security vulnerability, please use the `Tidelift security contact <https://tidelift.com/security>`__. Tidelift will coordinate the fix and disclosure.
  278. .. _MIT: https://github.com/pytest-dev/pytest-mock/blob/master/LICENSE