0
0
PytestHow-ToBeginner ยท 4 min read

How to Mock in pytest: Simple Guide with Examples

In pytest, you can mock functions or objects using the unittest.mock module, especially patch to replace parts of your code during tests. Use @patch as a decorator or context manager to control what the mocked object returns or how it behaves.
๐Ÿ“

Syntax

The main tool for mocking in pytest is unittest.mock.patch. You can use it as a decorator or a context manager.

  • @patch('target'): Replaces the target object with a mock during the test function.
  • with patch('target') as mock_obj: Temporarily mocks the target inside the block.
  • mock_obj.return_value: Sets what the mock returns when called.
  • mock_obj.assert_called_once(): Checks if the mock was called exactly once.
python
from unittest.mock import patch

import module

@patch('module.function_to_mock')
def test_example(mock_function):
    mock_function.return_value = 42
    result = module.function_to_mock()
    assert result == 42
    mock_function.assert_called_once()
๐Ÿ’ป

Example

This example shows how to mock a function that returns a value, so the test does not call the real function but uses the mocked return value instead.

python
from unittest.mock import patch

def get_data():
    # Imagine this calls a slow API or database
    return 10

def process_data():
    value = get_data()
    return value * 2

@patch('__main__.get_data')
def test_process_data(mock_get_data):
    mock_get_data.return_value = 5
    result = process_data()
    assert result == 10
    mock_get_data.assert_called_once()
โš ๏ธ

Common Pitfalls

Common mistakes when mocking in pytest include:

  • Mocking the wrong import path. You must patch where the function or object is used, not where it is defined.
  • Not setting return_value or side effects, causing mocks to return MagicMock objects unexpectedly.
  • Forgetting to assert that mocks were called, missing verification of behavior.
python
from unittest.mock import patch

# Wrong: patching the original module, not where used
@patch('module.function_to_mock')
def test_wrong_patch(mock_func):
    mock_func.return_value = 1
    # This might not mock correctly if function_to_mock is imported elsewhere

# Right: patch where function is used
@patch('__main__.function_to_mock')
def test_right_patch(mock_func):
    mock_func.return_value = 1
    # Correct mocking here
๐Ÿ“Š

Quick Reference

ConceptDescriptionExample
patch decoratorMocks target during test function@patch('module.func')
patch context managerMocks target inside with blockwith patch('module.func') as mock:
return_valueSets mock return valuemock.return_value = 10
assert_called_onceChecks mock was called oncemock.assert_called_once()
side_effectDefines behavior or exceptionsmock.side_effect = Exception('fail')
โœ…

Key Takeaways

Use unittest.mock.patch to replace functions or objects during pytest tests.
Always patch the object where it is used, not where it is defined.
Set return_value or side_effect on mocks to control their behavior.
Assert mock calls to verify your code interacts as expected.
Use patch as a decorator or context manager for flexible mocking.