How to Mock return_value with MagicMock in Python unittest
Use unittest.mock.MagicMock to replace a dependency and set return_value to control what a mocked method returns during unit tests.
Python code
31 linesimport unittest
from unittest.mock import MagicMock
class PaymentGateway:
def charge(self, amount):
raise NotImplementedError
class OrderService:
def __init__(self, gateway):
self.gateway = gateway
def process_order(self, amount):
return self.gateway.charge(amount)
class TestOrderService(unittest.TestCase):
def test_process_order_returns_charge_result(self):
gateway = MagicMock()
gateway.charge.return_value = {"status": "success"}
service = OrderService(gateway)
result = service.process_order(100)
self.assertEqual(result, {"status": "success"})
gateway.charge.assert_called_once_with(100)
if __name__ == "__main__":
unittest.main()
Output
Ran 1 test in 0.002s
OK
How it works
MagicMock automatically creates mock methods and attributes when accessed, so gateway.charge is a mock object you can configure. Setting return_value tells that mock what to return when called, which lets you test OrderService in isolation without a real PaymentGateway. The assert_called_once_with(100) verifies the gateway was called exactly once with the correct argument. Because MagicMock mimics any object, it fits cleanly into dependency injection patterns.
Common mistakes
- Using `return_value` on the mock itself instead of on the specific method mock, e.g. `gateway.return_value` instead of `gateway.charge.return_value`.
- Forgetting to call `assert_called_once_with` or using it on the wrong mock method.
- Creating a new MagicMock inside the test but not injecting it into the service, so the mock never gets used.
Variations
- Use `spec=PaymentGateway` to restrict mock attributes to those on the real class.
- Use `side_effect` to return different values on consecutive calls or raise exceptions.
Real-world use cases
- Testing an order service without hitting a real payment provider, returning a fixed success payload per test.
- Simulating error responses from an external API to verify your code handles failures gracefully.
- Mocking database session objects in repository tests to avoid live database dependencies.
Sponsored
More from Testing & modern typing
- Capture stdout and stderr with pytest capsys easy
- Characterization Test for Legacy Python Code medium
- Dataclass with Type Hints Fields in Python easy
- Dependency Injection in Python for Testability easy
- Design Data Helpers with Python TypedDict and Literal easy
- Fix and Test a Regression Bug in Python with Unit Tests easy
Keep learning
Related tutorials and quizzes for this topic.