Explaining Monkeypatching in Pytest
The aim of this page📝 is to understand monkeypatching as a fixture, which is not a mock — to make sense of unit testing terminology, using Python’s Pytest, with a particular example and a usable syntax.
2 min readMay 4, 2023
First, the monkeypatch `setattr` method allows you to “simulate” the product of any function to whatever you want — for example…
- This is the tested function
- This is the unit test
- the call of
get_selected_stack()
is - at runtime - replaced by ...a call tolambda
defined to simply and always return the tuple("1", "aws_mini")
- the call of
get_selected_component(stack_choice, selected_stack)
is - at runtime replaced by - ...a call to
lambda _, __
(the number of arguments must be handled in lambda definition!) - ......define to simply and always return
"password"
In general, monkeypatch is an instance of a fixture — which can be contrasted to mock, another important concept in testing
We’re going to look at monkeypatch
but there are other fixtures, just to get an idea of what family we're in
When it comes to monkeypatch, it’s a general term for runtime dynamic modification of a piece of code
- Monkeypatching is a general term and not specific to pytest.
- It refers to the dynamic modification of a piece of code at runtime.
- In Python, it refers to dynamic modifications of a class or module at runtime.
- In other words, You do not execute the function, you use a fixture (a different function) that returns fake, pre-defined, static data … mainly and essentially, you are not using the real data (which you indeed should)
- Pytest has a monkeypatch fixture that helps you safely set/delete an attribute, dictionary item or environment variable, or to modify sys.path for importing.
monkeypatch
fixture has many methods in pytest
for Python
All modifications will be undone after the requesting test function or fixture finishes
the setattr
method of monkeypatch
fixture is the one I'm using the most
- Target is the path to the function you want to mock
- Name is the name of the function you want to mock
value
is the mocking function; if you just want a value uselambda _:<value>