How to Mock Function in pytest: Simple Guide with Examples
To mock a function in
pytest, use unittest.mock.patch as a decorator or context manager to replace the target function with a mock during the test. This lets you control the function's output and verify calls without running the real code.Syntax
The basic syntax to mock a function in pytest uses unittest.mock.patch. You specify the full path to the function you want to mock as a string. You can use it as a decorator or a context manager.
- Decorator: Place
@patch('module.function')above your test function. - Context manager: Use
with patch('module.function') as mock_func:inside your test.
The mock object replaces the original function and can be configured to return values or check how it was called.
python
from unittest.mock import patch import module @patch('module.function_to_mock') def test_example(mock_function): mock_function.return_value = 'mocked!' result = module.function_to_mock() assert result == 'mocked!'
Example
This example shows how to mock a function get_data from a module data_source. The test replaces get_data with a mock that returns a fixed value, so the test does not depend on the real data source.
python
from unittest.mock import patch import pytest # Imagine this is in data_source.py # def get_data(): # return 'real data' # Function under test from data_source import get_data def process_data(): data = get_data() return data.upper() @patch('data_source.get_data') def test_process_data(mock_get_data): mock_get_data.return_value = 'mocked data' result = process_data() assert result == 'MOCKED DATA'
Common Pitfalls
Common mistakes when mocking functions in pytest include:
- Mocking the wrong import path. Always mock the function where it is used, not where it is defined.
- Not setting
return_valueor side effects, causing the mock to returnMagicMockobjects instead of expected values. - Forgetting to use
@patchorwith patch(), so the real function runs and tests become slow or flaky.
python
from unittest.mock import patch # Wrong: mocking the function where it is defined, not where used @patch('data_source.get_data') # Correct if process_data imports get_data from data_source def test_wrong_path(mock_get_data): mock_get_data.return_value = 'mocked' # If process_data imports get_data differently, this mock won't work # Right: mock where the function is used @patch('module_where_process_data_uses_get_data.get_data') def test_right_path(mock_get_data): mock_get_data.return_value = 'mocked' # This mock works correctly
Quick Reference
Tips for mocking functions in pytest:
- Use
unittest.mock.patchto replace functions during tests. - Always mock the function where it is imported and used, not where it is defined.
- Set
return_valueorside_effecton the mock to control behavior. - Use
@patchdecorator for simple cases orwith patch()for scoped mocking. - Check mock calls with
mock_function.assert_called_once()or similar assertions.
Key Takeaways
Use unittest.mock.patch to replace functions in pytest tests.
Mock the function where it is used, not where it is defined.
Set return_value on the mock to control its output.
Use @patch decorator or with patch() context manager as needed.
Verify mock calls with assertions like assert_called_once.