What if you could control any external call in your tests like a magic remote control?
Why Mock return values and side effects in PyTest? - Purpose & Use Cases
Imagine testing a function that calls an external service, like fetching weather data. Manually, you have to wait for the real service every time, which is slow and unreliable.
Manually testing with real services is slow, can fail due to network issues, and makes tests flaky. It's hard to test all scenarios, like errors or special responses, because you can't control the real service.
Using mock return values and side effects lets you pretend the external service responds instantly with exactly what you want. You can simulate success, errors, or delays easily, making tests fast, reliable, and thorough.
def test_weather(): data = get_real_weather() assert data['temp'] > 0
from unittest.mock import Mock mock_service = Mock() mock_service.get_weather.return_value = {'temp': 20} assert mock_service.get_weather()['temp'] > 0
It enables fast, reliable tests that cover all cases by controlling what external calls return or do.
Testing a payment system where you mock the bank API to simulate success, failure, or timeout without real money transfers.
Manual testing with real dependencies is slow and unreliable.
Mocking return values and side effects simulates external calls easily.
This makes tests faster, stable, and able to cover all scenarios.
Practice
mock.return_value do in a pytest mock object?Solution
Step 1: Understand the role of
Thereturn_valuereturn_valueattribute sets a fixed return value for the mock when it is called.Step 2: Differentiate from other mock features
Unlikeside_effectwhich can raise exceptions or return different values,return_valuealways returns the same fixed value.Final Answer:
It defines a fixed value that the mock returns when called. -> Option BQuick Check:
return_value = fixed return [OK]
- Confusing return_value with side_effect
- Thinking return_value raises exceptions
- Assuming return_value tracks call count
Solution
Step 1: Identify how to raise exceptions with mocks
Settingside_effectto an exception causes the mock to raise that exception when called.Step 2: Check syntax correctness
Onlymock.side_effect = Exception('Error')is valid syntax to raise an exception on call.Final Answer:
mock.side_effect = Exception('Error') -> Option AQuick Check:
side_effect raises exceptions [OK]
- Using return_value to raise exceptions
- Using non-existent attributes like raise_exception
- Confusing syntax for exception raising
from unittest.mock import Mock mock = Mock() mock.side_effect = [1, 2, 3] print(mock()) print(mock()) print(mock())
Solution
Step 1: Understand side_effect as a list
Whenside_effectis a list, each call to the mock returns the next item in the list.Step 2: Trace each call output
First call returns 1, second returns 2, third returns 3, so printed outputs are 1, 2, 3.Final Answer:
1 2 3 -> Option AQuick Check:
side_effect list returns items in order [OK]
- Expecting entire list returned each call
- Confusing return_value with side_effect list
- Assuming calls after list ends raise error
from unittest.mock import Mock
mock = Mock()
mock.side_effect = Exception('Fail')
mock.side_effect = [1, 2, 3]
print(mock())Solution
Step 1: Analyze multiple side_effect assignments
The second assignment toside_effectreplaces the first one; no error occurs.Step 2: Understand mock call behavior
After settingside_effect = [1, 2, 3], the mock returns 1 on first call, soprint(mock())outputs 1.Final Answer:
The second assignment overwrites the first, no error occurs -> Option CQuick Check:
Last side_effect assignment wins [OK]
- Thinking multiple side_effect assignments cause errors
- Expecting exception to be raised immediately
- Confusing assignment with raising exceptions
Solution
Step 1: Understand side_effect list behavior
Whenside_effectis a list, the mock returns successive items from the list on each call. Non-callable items like numbers or exception instances are returned directly.Step 2: Recognize exception raising in side_effect list
Placing an exception instance directly returns it as a value, not raises it. To raise, use a generator expression that throws the exception.Step 3: Analyze options
mock.side_effect = [10, ValueError('bad'), 20] returns the exception object instead of raising it. mock.side_effect = [10, lambda: (_ for _ in ()).throw(ValueError('bad')), 20] uses a generator expression to raise ValueError on second call, returning 10 and 20 on first and third calls respectively.Final Answer:
mock.side_effect = [10, lambda: (_ for _ in ()).throw(ValueError('bad')), 20] -> Option DQuick Check:
Use generator throw to raise exceptions in side_effect list [OK]
- Putting exception instance directly in side_effect list
- Trying to set multiple return_values
- Using lambda returning list instead of generator throw
Ready to prove it?
Pass the test and this pattern moves unknown
