Skip to content

Commit d0b53d6

Browse files
authored
Merge pull request #10221 from pytest-dev/backport-10217-to-7.1.x
[7.1.x] Add reference to the Where to patch docs in monkeypatch.setattr
2 parents 13fd967 + 9b2c6ce commit d0b53d6

File tree

2 files changed

+42
-19
lines changed

2 files changed

+42
-19
lines changed

doc/en/how-to/monkeypatch.rst

+11-13
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,16 @@ environment variable, or to modify ``sys.path`` for importing.
1414
The ``monkeypatch`` fixture provides these helper methods for safely patching and mocking
1515
functionality in tests:
1616

17-
.. code-block:: python
17+
* :meth:`monkeypatch.setattr(obj, name, value, raising=True) <pytest.MonkeyPatch.setattr>`
18+
* :meth:`monkeypatch.delattr(obj, name, raising=True) <pytest.MonkeyPatch.delattr>`
19+
* :meth:`monkeypatch.setitem(mapping, name, value) <pytest.MonkeyPatch.setitem>`
20+
* :meth:`monkeypatch.delitem(obj, name, raising=True) <pytest.MonkeyPatch.delitem>`
21+
* :meth:`monkeypatch.setenv(name, value, prepend=None) <pytest.MonkeyPatch.setenv>`
22+
* :meth:`monkeypatch.delenv(name, raising=True) <pytest.MonkeyPatch.delenv>`
23+
* :meth:`monkeypatch.syspath_prepend(path) <pytest.MonkeyPatch.syspath_prepend>`
24+
* :meth:`monkeypatch.chdir(path) <pytest.MonkeyPatch.chdir>`
25+
* :meth:`monkeypatch.context() <pytest.MonkeyPatch.context>`
1826

19-
monkeypatch.setattr(obj, name, value, raising=True)
20-
monkeypatch.setattr("somemodule.obj.name", value, raising=True)
21-
monkeypatch.delattr(obj, name, raising=True)
22-
monkeypatch.setitem(mapping, name, value)
23-
monkeypatch.delitem(obj, name, raising=True)
24-
monkeypatch.setenv(name, value, prepend=None)
25-
monkeypatch.delenv(name, raising=True)
26-
monkeypatch.syspath_prepend(path)
27-
monkeypatch.chdir(path)
28-
monkeypatch.context()
2927

3028
All modifications will be undone after the requesting
3129
test function or fixture has finished. The ``raising``
@@ -64,8 +62,8 @@ and a discussion of its motivation.
6462

6563
.. _`monkeypatch blog post`: https://tetamap.wordpress.com//2009/03/03/monkeypatching-in-unit-tests-done-right/
6664

67-
Simple example: monkeypatching functions
68-
----------------------------------------
65+
Monkeypatching functions
66+
------------------------
6967

7068
Consider a scenario where you are working with user directories. In the context of
7169
testing, you do not want your test to depend on the running user. ``monkeypatch``

src/_pytest/monkeypatch.py

+31-6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def monkeypatch() -> Generator["MonkeyPatch", None, None]:
4040
* :meth:`monkeypatch.delenv(name, raising=True) <pytest.MonkeyPatch.delenv>`
4141
* :meth:`monkeypatch.syspath_prepend(path) <pytest.MonkeyPatch.syspath_prepend>`
4242
* :meth:`monkeypatch.chdir(path) <pytest.MonkeyPatch.chdir>`
43+
* :meth:`monkeypatch.context() <pytest.MonkeyPatch.context>`
4344
4445
All modifications will be undone after the requesting test function or
4546
fixture has finished. The ``raising`` parameter determines if a :class:`KeyError`
@@ -186,16 +187,40 @@ def setattr(
186187
value: object = notset,
187188
raising: bool = True,
188189
) -> None:
189-
"""Set attribute value on target, memorizing the old value.
190+
"""
191+
Set attribute value on target, memorizing the old value.
192+
193+
For example:
194+
195+
.. code-block:: python
196+
197+
import os
198+
199+
monkeypatch.setattr(os, "getcwd", lambda: "/")
200+
201+
The code above replaces the :func:`os.getcwd` function by a ``lambda`` which
202+
always returns ``"/"``.
190203
191-
For convenience you can specify a string as ``target`` which
204+
For convenience, you can specify a string as ``target`` which
192205
will be interpreted as a dotted import path, with the last part
193-
being the attribute name. For example,
194-
``monkeypatch.setattr("os.getcwd", lambda: "/")``
195-
would set the ``getcwd`` function of the ``os`` module.
206+
being the attribute name:
196207
197-
Raises AttributeError if the attribute does not exist, unless
208+
.. code-block:: python
209+
210+
monkeypatch.setattr("os.getcwd", lambda: "/")
211+
212+
Raises :class:`AttributeError` if the attribute does not exist, unless
198213
``raising`` is set to False.
214+
215+
**Where to patch**
216+
217+
``monkeypatch.setattr`` works by (temporarily) changing the object that a name points to with another one.
218+
There can be many names pointing to any individual object, so for patching to work you must ensure
219+
that you patch the name used by the system under test.
220+
221+
See the section :ref:`Where to patch <python:where-to-patch>` in the :mod:`unittest.mock`
222+
docs for a complete explanation, which is meant for :func:`unittest.mock.patch` but
223+
applies to ``monkeypatch.setattr`` as well.
199224
"""
200225
__tracebackhide__ = True
201226
import inspect

0 commit comments

Comments
 (0)