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.

Pavol Kutaj
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 to lambda 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 use lambda _:<value>

LINKS

--

--

Pavol Kutaj

Today I Learnt | Infrastructure Support Engineer at snowplow.io with a passion for cloud infrastructure/terraform/python/docs. More at https://pavol.kutaj.com