Python > Testing in Python > Mocking and Patching > Patching Objects and Functions
Patching a Class Attribute for Testing
This example demonstrates how to use unittest.mock.patch
to temporarily replace a class attribute during a test. This is particularly useful when you need to control the behavior of a class without modifying its actual implementation.
Concepts Behind Patching Class Attributes
Patching class attributes involves replacing the value of an attribute defined directly within a class definition. This allows you to simulate different states or configurations for your class during testing. The unittest.mock.patch
decorator or context manager is used to achieve this. When the test is complete, the original value of the class attribute is restored.
Code Example: Patching a Class Attribute
This code defines a class MyClass
with a class attribute CONSTANT_VALUE
. The TestMyClass
contains two test methods. The first test method, test_calculate_with_patched_constant
, uses the @patch
decorator to temporarily replace MyClass.CONSTANT_VALUE
with 20
. Inside this test, the calculate
method is called, and the result is asserted to be 40
(20 * 2). The second test method, test_calculate_without_patch
, calls the calculate
method without any patching, so the original CONSTANT_VALUE
of 10
is used, resulting in a value of 20
. The patch target is specified as a string indicating the full path to the class attribute to be patched.
import unittest
from unittest.mock import patch
class MyClass:
CONSTANT_VALUE = 10
def calculate(self):
return self.CONSTANT_VALUE * 2
class TestMyClass(unittest.TestCase):
@patch('__main__.MyClass.CONSTANT_VALUE', 20)
def test_calculate_with_patched_constant(self):
instance = MyClass()
result = instance.calculate()
self.assertEqual(result, 40)
def test_calculate_without_patch(self):
instance = MyClass()
result = instance.calculate()
self.assertEqual(result, 20)
if __name__ == '__main__':
unittest.main()
Real-Life Use Case
Imagine a class that uses a configuration setting loaded from a file or environment variable. During testing, you might want to override this setting to test different scenarios without modifying the configuration file or environment. Patching the class attribute holding the configuration value allows you to isolate the test and ensure consistent results.
Best Practices
patch
decorator automatically restores the original value after the test completes.
Interview Tip
Be prepared to explain the importance of mocking and patching in testing, especially when dealing with external dependencies or complex interactions. Explain how patching helps isolate units of code and facilitates controlled testing environments. Discuss the benefits of using decorators vs. context managers for patching, and the scenarios where each is more appropriate.
When to Use Patching Class Attributes
Use patching class attributes when:
Alternatives
Alternatives to patching class attributes include:
Pros
Cons
FAQ
-
What happens if the patched attribute doesn't exist?
Thepatch
decorator will raise anAttributeError
if the specified attribute does not exist. Ensure the target of the patch is correct. -
How do I patch multiple attributes in a single test?
You can use multiple@patch
decorators, one for each attribute you want to patch, or use a single@patch.multiple
decorator for more complex scenarios.