What if you could change how your code behaves just for tests, without touching the real code?
Why monkeypatch.setattr in PyTest? - Purpose & Use Cases
Imagine you have a function that calls another function to get data from the internet. You want to test your function without actually making the slow network call every time.
Doing this manually means changing the original code or running the real network call during tests.
Manually changing code to avoid network calls is risky and time-consuming.
Running real network calls in tests makes tests slow and flaky because of internet issues.
It's easy to forget to undo changes, causing bugs later.
Using monkeypatch.setattr lets you temporarily replace parts of your code during tests.
You can swap the real network call with a fake function that returns quick, predictable data.
This keeps your tests fast, reliable, and safe without changing your real code.
def test_fetch(): # manually change code or call real network result = fetch_data() assert result == expected
def test_fetch(monkeypatch): monkeypatch.setattr('module.fetch_data', lambda: 'fake data') result = module.fetch_data() assert result == 'fake data'
You can test code parts in isolation by swapping real functions with fake ones easily and safely.
Testing a weather app without calling the real weather service every time by replacing the data fetch function with a fixed response.
Manual code changes for testing are slow and risky.
monkeypatch.setattr swaps functions temporarily during tests.
This makes tests faster, safer, and more reliable.
Practice
monkeypatch.setattr in pytest?Solution
Step 1: Understand monkeypatch.setattr usage
It is used to temporarily replace or modify attributes or functions during a test to isolate behavior.Step 2: Differentiate from other pytest features
It does not permanently change code or skip tests; it only affects the test scope temporarily.Final Answer:
To temporarily replace an attribute or function during a test -> Option AQuick Check:
Temporary replacement = A [OK]
- Confusing temporary patching with permanent code changes
- Thinking it skips tests
- Assuming it runs tests in parallel
get_data in module my_module using monkeypatch in pytest?Solution
Step 1: Identify correct monkeypatch.setattr signature
The correct usage is monkeypatch.setattr(target_object, attribute_name, new_value).Step 2: Match parameters to patch get_data function
We pass the module objectmy_module, the attribute name'get_data', and the replacement functionlambda: 42.Final Answer:
monkeypatch.setattr(my_module, 'get_data', lambda: 42) -> Option CQuick Check:
Object, attribute, new value = A [OK]
- Passing attribute as a string path instead of object and attribute
- Swapping parameters order
- Passing value instead of function for patching
import my_module
def test_func(monkeypatch):
def fake_func():
return 10
monkeypatch.setattr(my_module, 'get_value', fake_func)
result = my_module.get_value()
print(result)Solution
Step 1: Understand monkeypatch effect on get_value
The originalmy_module.get_valueis replaced temporarily byfake_funcwhich returns 10.Step 2: Evaluate the call and print output
Callingmy_module.get_value()inside the test callsfake_func(), so it prints 10.Final Answer:
10 -> Option DQuick Check:
Patched function returns 10 [OK]
- Expecting original function output instead of patched
- Thinking patch is permanent outside test
- Assuming print outputs None
def test_example(monkeypatch):
monkeypatch.setattr('os.path.exists', lambda x: True)
assert os.path.exists('anyfile.txt') == TrueSolution
Step 1: Check monkeypatch.setattr usage
The first argument must be the module or object, not a string path.Step 2: Identify correct usage
It should bemonkeypatch.setattr(os.path, 'exists', lambda x: True)to patch the function properly.Final Answer:
The first argument to setattr should be the module object, not a string -> Option BQuick Check:
Object, not string path = B [OK]
- Passing string path instead of module object
- Incorrect lambda parameters
- Assuming some functions cannot be patched
fetch_data() that calls requests.get. How can you use monkeypatch.setattr to replace requests.get with a fake function that returns a mock response with status_code=200 and text='OK'?Solution
Step 1: Create a fake function returning a mock response
Define a function that returns an object withstatus_code=200andtext='OK'.Step 2: Patch requests.get with monkeypatch.setattr
Usemonkeypatch.setattr(requests, 'get', fake_func)to replace the real HTTP call during the test.Final Answer:
Define a fake function returning a mock object, then patch with monkeypatch.setattr(requests, 'get', fake_func) -> Option AQuick Check:
Patch requests.get with fake function = D [OK]
- Passing string path instead of module object
- Patching with wrong types like strings
- Replacing the wrong function instead of requests.get
Ready to prove it?
Pass the test and this pattern moves unknown
