0
# Patching
1
2
Patching allows temporary replacement of objects with mocks during testing. The mock library provides several patching mechanisms that work as context managers, decorators, or manual start/stop operations.
3
4
## Capabilities
5
6
### patch
7
8
The main patching function that replaces objects with mocks temporarily.
9
10
```python { .api }
11
def patch(
12
target,
13
new=None,
14
spec=None,
15
create=False,
16
spec_set=None,
17
autospec=None,
18
new_callable=None,
19
*,
20
unsafe=False,
21
**kwargs
22
):
23
"""
24
Replace target object with a mock.
25
26
Parameters:
27
- target: String specifying the target to patch (e.g., 'module.ClassName')
28
- new: Object to replace target with (defaults to MagicMock)
29
- spec: Specification for the mock
30
- create: Create target if it doesn't exist
31
- spec_set: More restrictive spec
32
- autospec: Create mock with automatic spec
33
- new_callable: Alternative to new, called to create replacement
34
- unsafe: Allow access to dangerous attributes
35
- **kwargs: Additional arguments passed to mock constructor
36
37
Returns:
38
Mock object (when used as context manager or started manually)
39
"""
40
```
41
42
### patch.object
43
44
Patch a named attribute on an object.
45
46
```python { .api }
47
def patch.object(
48
target,
49
attribute,
50
new=None,
51
spec=None,
52
create=False,
53
spec_set=None,
54
autospec=None,
55
new_callable=None,
56
**kwargs
57
):
58
"""
59
Patch a named attribute on an object.
60
61
Parameters:
62
- target: Object to patch
63
- attribute: String name of attribute to patch
64
- new: Replacement object (defaults to MagicMock)
65
- spec: Specification for the mock
66
- create: Create attribute if it doesn't exist
67
- spec_set: More restrictive spec
68
- autospec: Create mock with automatic spec
69
- new_callable: Alternative to new, called to create replacement
70
- **kwargs: Additional arguments passed to mock constructor
71
72
Returns:
73
Mock object (when used as context manager or started manually)
74
"""
75
```
76
77
### patch.multiple
78
79
Patch multiple attributes on a target object simultaneously.
80
81
```python { .api }
82
def patch.multiple(
83
target,
84
spec=None,
85
create=False,
86
spec_set=None,
87
autospec=None,
88
new_callable=None,
89
**kwargs
90
):
91
"""
92
Patch multiple attributes on a target object.
93
94
Parameters:
95
- target: Object or string specifying target to patch
96
- spec: Specification for the mocks
97
- create: Create attributes if they don't exist
98
- spec_set: More restrictive spec
99
- autospec: Create mocks with automatic spec
100
- new_callable: Alternative callable for creating mocks
101
- **kwargs: attribute_name=replacement pairs
102
103
Returns:
104
Dictionary of attribute names to mock objects
105
"""
106
```
107
108
### patch.dict
109
110
Context manager for patching dictionaries, including environment variables and module-level dictionaries.
111
112
```python { .api }
113
class patch.dict:
114
def __init__(
115
self,
116
in_dict,
117
values=(),
118
clear=False,
119
**keywds
120
):
121
"""
122
Patch a dictionary or dictionary-like object.
123
124
Parameters:
125
- in_dict: Dictionary to patch or string specifying target
126
- values: Dictionary or iterable of (key, value) pairs to set
127
- clear: Clear dictionary before setting values
128
- **keywds: Keyword arguments for values to set
129
"""
130
131
def __enter__(self):
132
"""Enter context manager, apply patches."""
133
134
def __exit__(self, *args):
135
"""Exit context manager, restore original values."""
136
137
def start(self):
138
"""Start patching manually."""
139
140
def stop(self):
141
"""Stop patching manually."""
142
```
143
144
### Patch Object Methods
145
146
All patch objects (returned by patch, patch.object, patch.multiple) support manual start/stop control:
147
148
```python { .api }
149
class _patch:
150
def start(self):
151
"""
152
Start patching manually.
153
154
Returns:
155
Mock object that replaces the target
156
"""
157
158
def stop(self):
159
"""
160
Stop patching manually.
161
162
Restores original object and cleans up.
163
"""
164
165
def __enter__(self):
166
"""Context manager entry - equivalent to start()."""
167
168
def __exit__(self, *args):
169
"""Context manager exit - equivalent to stop()."""
170
```
171
172
### Patch Management
173
174
```python { .api }
175
def stop_all():
176
"""
177
Stop all active patches that were started with start().
178
179
This function stops all patches that are currently active
180
from manual start() calls. Does not affect context manager
181
or decorator patches.
182
"""
183
```
184
185
## Usage Patterns
186
187
### Context Manager Usage
188
189
```python
190
from mock import patch
191
192
# Basic patching
193
with patch('module.function') as mock_func:
194
mock_func.return_value = 'mocked'
195
# Code using module.function() will get 'mocked'
196
197
# Object attribute patching
198
with patch.object(obj, 'method') as mock_method:
199
mock_method.return_value = 'result'
200
# obj.method() will return 'result'
201
202
# Multiple patching
203
with patch.multiple('module', func1='mock1', func2='mock2') as mocks:
204
# module.func1 and module.func2 are now mocked
205
# mocks is {'func1': mock1, 'func2': mock2}
206
```
207
208
### Decorator Usage
209
210
```python
211
from mock import patch
212
213
@patch('module.function')
214
def test_something(mock_func):
215
mock_func.return_value = 42
216
# Test code here
217
218
@patch.object(MyClass, 'method')
219
def test_method(mock_method):
220
mock_method.return_value = 'mocked'
221
# Test code here
222
223
# Multiple decorators stack bottom-to-top
224
@patch('module.func2')
225
@patch('module.func1')
226
def test_multiple(mock_func1, mock_func2):
227
# Arguments passed in reverse order of decorators
228
pass
229
```
230
231
### Manual Start/Stop
232
233
```python
234
from mock import patch
235
236
# Start patch manually
237
patcher = patch('module.function')
238
mock_func = patcher.start()
239
mock_func.return_value = 'mocked'
240
241
try:
242
# Test code here
243
pass
244
finally:
245
patcher.stop()
246
247
# Or use stop_all to stop all active patches
248
from mock import stop_all
249
stop_all()
250
```
251
252
### Dictionary Patching
253
254
```python
255
from mock import patch
256
import os
257
258
# Patch environment variables
259
with patch.dict(os.environ, {'KEY': 'value'}):
260
# os.environ['KEY'] is now 'value'
261
pass
262
263
# Patch module-level dictionary
264
module_dict = {'key': 'original'}
265
with patch.dict(module_dict, {'key': 'new', 'extra': 'added'}):
266
# module_dict now contains updated values
267
pass
268
269
# Clear and replace
270
with patch.dict(module_dict, {'only': 'this'}, clear=True):
271
# module_dict only contains {'only': 'this'}
272
pass
273
```
274
275
### Advanced Patching
276
277
```python
278
from mock import patch, Mock
279
280
# Create patch if target doesn't exist
281
with patch('nonexistent.module.func', create=True) as mock_func:
282
mock_func.return_value = 'created'
283
284
# Use autospec for automatic specification
285
with patch('module.Class', autospec=True) as MockClass:
286
# MockClass has same signature as original Class
287
instance = MockClass()
288
289
# Custom replacement
290
def custom_replacement(*args, **kwargs):
291
return 'custom result'
292
293
with patch('module.func', new=custom_replacement):
294
# module.func is replaced with custom_replacement
295
pass
296
297
# Using new_callable
298
with patch('module.func', new_callable=lambda: Mock(return_value='called')):
299
# Creates new mock instance each time
300
pass
301
```
302
303
## Common Patterns
304
305
### Testing External Dependencies
306
307
```python
308
from mock import patch
309
import requests
310
311
@patch('requests.get')
312
def test_api_call(mock_get):
313
# Mock HTTP response
314
mock_response = Mock()
315
mock_response.json.return_value = {'data': 'test'}
316
mock_response.status_code = 200
317
mock_get.return_value = mock_response
318
319
# Test code that calls requests.get
320
result = api_function()
321
assert result == {'data': 'test'}
322
mock_get.assert_called_once()
323
```
324
325
### Patching Methods on Instances
326
327
```python
328
from mock import patch
329
330
class MyClass:
331
def method(self): pass
332
333
obj = MyClass()
334
335
# Patch method on specific instance
336
with patch.object(obj, 'method', return_value='mocked'):
337
result = obj.method()
338
assert result == 'mocked'
339
340
# Patch method on class (affects all instances)
341
with patch.object(MyClass, 'method', return_value='mocked'):
342
result = obj.method()
343
assert result == 'mocked'
344
```