0
0
PytestHow-ToBeginner ยท 4 min read

How to Use Monkeypatch in pytest for Easy Testing

Use pytest's monkeypatch fixture to temporarily change or replace attributes, environment variables, or functions during a test. It helps isolate tests by modifying behavior without permanent changes. Simply add monkeypatch as a test argument and call its methods like setattr or setenv.
๐Ÿ“

Syntax

The monkeypatch fixture is used by adding it as a parameter to your test function. You then call its methods to patch objects temporarily.

  • monkeypatch.setattr(target, name, value): Replace an attribute or method.
  • monkeypatch.setenv(name, value): Set an environment variable.
  • monkeypatch.delattr(target, name): Remove an attribute.
  • monkeypatch.delenv(name): Remove an environment variable.
python
def test_example(monkeypatch):
    monkeypatch.setattr('module.Class.attribute', 'new_value')
    monkeypatch.setenv('ENV_VAR', 'value')
๐Ÿ’ป

Example

This example shows how to use monkeypatch to replace a function during a test. The original function returns a fixed value, but the test changes it to return a different value temporarily.

python
import pytest

def get_data():
    return 'original data'

def test_monkeypatch_function(monkeypatch):
    def fake_get_data():
        return 'patched data'

    monkeypatch.setattr(__name__, 'get_data', fake_get_data)

    result = get_data()
    assert result == 'patched data'

    # Outside test, get_data returns original
    # monkeypatch.undo()  # optional, pytest does this automatically
โš ๏ธ

Common Pitfalls

Common mistakes when using monkeypatch include:

  • Not passing monkeypatch as a test argument.
  • Using incorrect target strings for setattr (must be full import path or module reference).
  • Forgetting that patches are temporary and reset after each test.
  • Trying to patch built-in functions without proper reference.

Always check the target path and use monkeypatch only inside test functions.

python
import pytest

def test_wrong():
    # Wrong: missing monkeypatch argument
    # monkeypatch.setattr('module.func', lambda: 1)  # This will fail
    pass

def test_right(monkeypatch):
    monkeypatch.setattr('builtins.open', lambda *args, **kwargs: 'mocked')
    assert open() == 'mocked'
๐Ÿ“Š

Quick Reference

MethodPurposeExample Usage
setattr(target, name, value)Replace attribute or methodmonkeypatch.setattr('module.func', fake_func)
setenv(name, value)Set environment variablemonkeypatch.setenv('KEY', 'value')
delattr(target, name)Remove attributemonkeypatch.delattr('module.attr')
delenv(name)Remove environment variablemonkeypatch.delenv('KEY')
โœ…

Key Takeaways

Add monkeypatch as a test function argument to use it.
Use monkeypatch.setattr to replace functions or attributes temporarily.
monkeypatch changes last only during the test and revert automatically.
Always provide correct target paths when patching with monkeypatch.
Use monkeypatch to isolate tests by controlling external dependencies safely.