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.

Medium Python 3.9+ Aug 9, 2026 Testing & modern typing 14 views 0 copies

Python code

33 lines
Python 3.9+
import 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

stdout
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

  1. Use context manager: `with patch.object(Calculator, 'add', return_value=100) as mock_add:` for explicit scope control.
  2. 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

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Testing & modern typing

Related tutorials and quizzes for this topic.