How to Mock an Object Method in Python unittest
Mock a method on an instance or class with @patch.object, set its return value, and assert its call arguments in Python unittest.
Python code
33 linesimport unittest
from unittest.mock import patch
class Calculator:
def add(self, a, b):
return a + b
def multiply(self, a, b):
return a * b
class TestCalculator(unittest.TestCase):
def test_add_normal(self):
calc = Calculator()
result = calc.add(2, 3)
self.assertEqual(result, 5)
@patch.object(Calculator, 'add', return_value=100)
def test_add_mocked(self, mock_add):
calc = Calculator()
result = calc.add(2, 3)
self.assertEqual(result, 100)
mock_add.assert_called_once_with(2, 3)
@patch.object(Calculator, 'multiply')
def test_multiply_mocked(self, mock_multiply):
mock_multiply.return_value = 42
calc = Calculator()
result = calc.multiply(6, 7)
self.assertEqual(result, 42)
mock_multiply.assert_called_once_with(6, 7)
if __name__ == "__main__":
unittest.main(verbosity=2)
Output
test_add_mocked (__main__.TestCalculator.test_add_mocked) ... ok
test_add_normal (__main__.TestCalculator.test_add_normal) ... ok
test_multiply_mocked (__main__.TestCalculator.test_multiply_mocked) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
How it works
@patch.object(ClassName, 'method') replaces the method with a MagicMock for the duration of the test, then restores it automatically. If you pass return_value in the decorator, the mock always returns that value. Otherwise you can set mock.return_value inside the test. The mock is passed as the test method's argument, which you use for assertions like assert_called_once_with. Because the patch targets the class, it also affects existing instances, so Calculator() inside the test uses the mocked method.
Common mistakes
- Forgetting to accept the mock as an argument in the test method when using a patch decorator.
- Patching an instance method as `@patch.object(calc, 'add')` instead of the class, so the mock is lost after restart.
- Setting `return_value` twice (e.g., in decorator and again in test) causing confusion.
- Using `assert_called_once_with` without knowing the exact call arguments, causing false failures.
Variations
- Use context manager: `with patch.object(Calculator, 'add', return_value=100) as mock_add:` for explicit scope control.
- Use `patch('module.Calculator.add')` with string path when patching imported classes in other modules.
Real-world use cases
- Isolating unit tests for a service that calls an external API by mocking the HTTP client method.
- Testing error handling by forcing a database method to raise an exception via side_effect.
- Simulating flaky third-party functions in CI to verify retry logic deterministically.
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.