0
0
PytestHow-ToBeginner ยท 3 min read

How to Use patch in pytest for Mocking Dependencies

Use patch from unittest.mock in pytest to temporarily replace objects or functions during tests. Apply patch as a decorator or context manager to mock dependencies and control their behavior.
๐Ÿ“

Syntax

The patch function is used to replace a target object with a mock during a test. It can be applied as a decorator or a context manager.

  • Decorator: @patch('module.ClassName') replaces ClassName in module with a mock for the test function.
  • Context manager: with patch('module.function_name') as mock_func: temporarily replaces function_name with a mock inside the block.
python
from unittest.mock import patch

# As a decorator
@patch('module.ClassName')
def test_example_decorator(mock_class):
    pass

# As a context manager
def test_example_context_manager():
    with patch('module.function_name') as mock_func:
        pass
๐Ÿ’ป

Example

This example shows how to use patch to mock a function that returns a fixed value during a test, isolating the test from external dependencies.

python
from unittest.mock import patch

def get_data():
    # Imagine this fetches data from an API
    return {'value': 42}

def process_data():
    data = get_data()
    return data['value'] * 2

def test_process_data():
    with patch('__main__.get_data', return_value={'value': 10}):
        result = process_data()
        assert result == 20
โš ๏ธ

Common Pitfalls

Common mistakes when using patch include:

  • Incorrect target string: Always patch where the object is used, not where it is defined.
  • Forgetting to specify the correct import path in the patch target.
  • Not using return_value or side_effect to control mock behavior.

Example of wrong and right patch target:

python
from unittest.mock import patch

def test_wrong_patch():
    # Wrong: patching the original module instead of where used
    with patch('module.get_data', return_value={'value': 5}):
        # This won't mock if process_data imports get_data differently
        pass

def test_right_patch():
    # Right: patch where get_data is used
    with patch('__main__.get_data', return_value={'value': 5}):
        pass
๐Ÿ“Š

Quick Reference

UsageDescription
@patch('module.ClassName')Mock a class or object as a decorator
with patch('module.function_name') as mock:Mock a function or object as a context manager
return_value=...Set the mock's return value
side_effect=...Set a function or exception to trigger on call
mock_object.assert_called_once()Assert the mock was called exactly once
โœ…

Key Takeaways

Use patch to replace dependencies temporarily during pytest tests for isolation.
Always patch the object where it is used, not where it is defined.
Use return_value or side_effect to control mock behavior.
Apply patch as a decorator or context manager depending on test needs.
Verify mock calls with assertions like assert_called_once.