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
monkeypatchas 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
| Method | Purpose | Example Usage |
|---|---|---|
| setattr(target, name, value) | Replace attribute or method | monkeypatch.setattr('module.func', fake_func) |
| setenv(name, value) | Set environment variable | monkeypatch.setenv('KEY', 'value') |
| delattr(target, name) | Remove attribute | monkeypatch.delattr('module.attr') |
| delenv(name) | Remove environment variable | monkeypatch.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.