Add reference to the Where to patch docs in monkeypatch.setattr (#10217)
This should help users with the common issue of patching the wrong place. Also took the opportunity of using proper links in the monkeypatch introduction. Related to #10216 Co-authored-by: Ran Benita <ran@unusedvar.com>
This commit is contained in:
parent
08dfd3124c
commit
2e7c718373
|
@ -14,18 +14,16 @@ environment variable, or to modify ``sys.path`` for importing.
|
||||||
The ``monkeypatch`` fixture provides these helper methods for safely patching and mocking
|
The ``monkeypatch`` fixture provides these helper methods for safely patching and mocking
|
||||||
functionality in tests:
|
functionality in tests:
|
||||||
|
|
||||||
.. code-block:: python
|
* :meth:`monkeypatch.setattr(obj, name, value, raising=True) <pytest.MonkeyPatch.setattr>`
|
||||||
|
* :meth:`monkeypatch.delattr(obj, name, raising=True) <pytest.MonkeyPatch.delattr>`
|
||||||
|
* :meth:`monkeypatch.setitem(mapping, name, value) <pytest.MonkeyPatch.setitem>`
|
||||||
|
* :meth:`monkeypatch.delitem(obj, name, raising=True) <pytest.MonkeyPatch.delitem>`
|
||||||
|
* :meth:`monkeypatch.setenv(name, value, prepend=None) <pytest.MonkeyPatch.setenv>`
|
||||||
|
* :meth:`monkeypatch.delenv(name, raising=True) <pytest.MonkeyPatch.delenv>`
|
||||||
|
* :meth:`monkeypatch.syspath_prepend(path) <pytest.MonkeyPatch.syspath_prepend>`
|
||||||
|
* :meth:`monkeypatch.chdir(path) <pytest.MonkeyPatch.chdir>`
|
||||||
|
* :meth:`monkeypatch.context() <pytest.MonkeyPatch.context>`
|
||||||
|
|
||||||
monkeypatch.setattr(obj, name, value, raising=True)
|
|
||||||
monkeypatch.setattr("somemodule.obj.name", value, raising=True)
|
|
||||||
monkeypatch.delattr(obj, name, raising=True)
|
|
||||||
monkeypatch.setitem(mapping, name, value)
|
|
||||||
monkeypatch.delitem(obj, name, raising=True)
|
|
||||||
monkeypatch.setenv(name, value, prepend=None)
|
|
||||||
monkeypatch.delenv(name, raising=True)
|
|
||||||
monkeypatch.syspath_prepend(path)
|
|
||||||
monkeypatch.chdir(path)
|
|
||||||
monkeypatch.context()
|
|
||||||
|
|
||||||
All modifications will be undone after the requesting
|
All modifications will be undone after the requesting
|
||||||
test function or fixture has finished. The ``raising``
|
test function or fixture has finished. The ``raising``
|
||||||
|
@ -64,8 +62,8 @@ and a discussion of its motivation.
|
||||||
|
|
||||||
.. _`monkeypatch blog post`: https://tetamap.wordpress.com//2009/03/03/monkeypatching-in-unit-tests-done-right/
|
.. _`monkeypatch blog post`: https://tetamap.wordpress.com//2009/03/03/monkeypatching-in-unit-tests-done-right/
|
||||||
|
|
||||||
Simple example: monkeypatching functions
|
Monkeypatching functions
|
||||||
----------------------------------------
|
------------------------
|
||||||
|
|
||||||
Consider a scenario where you are working with user directories. In the context of
|
Consider a scenario where you are working with user directories. In the context of
|
||||||
testing, you do not want your test to depend on the running user. ``monkeypatch``
|
testing, you do not want your test to depend on the running user. ``monkeypatch``
|
||||||
|
|
|
@ -40,6 +40,7 @@ def monkeypatch() -> Generator["MonkeyPatch", None, None]:
|
||||||
* :meth:`monkeypatch.delenv(name, raising=True) <pytest.MonkeyPatch.delenv>`
|
* :meth:`monkeypatch.delenv(name, raising=True) <pytest.MonkeyPatch.delenv>`
|
||||||
* :meth:`monkeypatch.syspath_prepend(path) <pytest.MonkeyPatch.syspath_prepend>`
|
* :meth:`monkeypatch.syspath_prepend(path) <pytest.MonkeyPatch.syspath_prepend>`
|
||||||
* :meth:`monkeypatch.chdir(path) <pytest.MonkeyPatch.chdir>`
|
* :meth:`monkeypatch.chdir(path) <pytest.MonkeyPatch.chdir>`
|
||||||
|
* :meth:`monkeypatch.context() <pytest.MonkeyPatch.context>`
|
||||||
|
|
||||||
All modifications will be undone after the requesting test function or
|
All modifications will be undone after the requesting test function or
|
||||||
fixture has finished. The ``raising`` parameter determines if a :class:`KeyError`
|
fixture has finished. The ``raising`` parameter determines if a :class:`KeyError`
|
||||||
|
@ -186,16 +187,40 @@ class MonkeyPatch:
|
||||||
value: object = notset,
|
value: object = notset,
|
||||||
raising: bool = True,
|
raising: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set attribute value on target, memorizing the old value.
|
"""
|
||||||
|
Set attribute value on target, memorizing the old value.
|
||||||
|
|
||||||
For convenience you can specify a string as ``target`` which
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
monkeypatch.setattr(os, "getcwd", lambda: "/")
|
||||||
|
|
||||||
|
The code above replaces the :func:`os.getcwd` function by a ``lambda`` which
|
||||||
|
always returns ``"/"``.
|
||||||
|
|
||||||
|
For convenience, you can specify a string as ``target`` which
|
||||||
will be interpreted as a dotted import path, with the last part
|
will be interpreted as a dotted import path, with the last part
|
||||||
being the attribute name. For example,
|
being the attribute name:
|
||||||
``monkeypatch.setattr("os.getcwd", lambda: "/")``
|
|
||||||
would set the ``getcwd`` function of the ``os`` module.
|
|
||||||
|
|
||||||
Raises AttributeError if the attribute does not exist, unless
|
.. code-block:: python
|
||||||
|
|
||||||
|
monkeypatch.setattr("os.getcwd", lambda: "/")
|
||||||
|
|
||||||
|
Raises :class:`AttributeError` if the attribute does not exist, unless
|
||||||
``raising`` is set to False.
|
``raising`` is set to False.
|
||||||
|
|
||||||
|
**Where to patch**
|
||||||
|
|
||||||
|
``monkeypatch.setattr`` works by (temporarily) changing the object that a name points to with another one.
|
||||||
|
There can be many names pointing to any individual object, so for patching to work you must ensure
|
||||||
|
that you patch the name used by the system under test.
|
||||||
|
|
||||||
|
See the section :ref:`Where to patch <python:where-to-patch>` in the :mod:`unittest.mock`
|
||||||
|
docs for a complete explanation, which is meant for :func:`unittest.mock.patch` but
|
||||||
|
applies to ``monkeypatch.setattr`` as well.
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
import inspect
|
import inspect
|
||||||
|
|
Loading…
Reference in New Issue