Explaining Monkeypatching in Python 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.
First of all, 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 to
lambdadefined to simply and always return the tuple
- the call of
get_selected_component(stack_choice, selected_stack)is - at runtime replaces by
- ...a call to
lambda _, __(the number of arguments must be handled in lambda definition!)
- ......define to simply and always return
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
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
valueis the mocking function; if you just want a value use