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_valueor side effects, causing mocks to returnMagicMockobjects 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
| Concept | Description | Example |
|---|---|---|
| patch decorator | Mocks target during test function | @patch('module.func') |
| patch context manager | Mocks target inside with block | with patch('module.func') as mock: |
| return_value | Sets mock return value | mock.return_value = 10 |
| assert_called_once | Checks mock was called once | mock.assert_called_once() |
| side_effect | Defines behavior or exceptions | mock.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.