or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-mocking.mdcore-mocking.mdindex.mdpatching.mdutilities.md

patching.mddocs/

0

# Patching System

1

2

Comprehensive patching decorators and context managers for temporarily replacing objects during testing. The patching system provides flexible strategies for dependency injection, object replacement, and test isolation with automatic cleanup.

3

4

## Capabilities

5

6

### Basic Patching

7

8

The main `patch` decorator and context manager for replacing objects during tests.

9

10

```python { .api }

11

def patch(

12

target: str,

13

new=..., # DEFAULT creates MagicMock/AsyncMock

14

spec=None,

15

create: bool = False,

16

spec_set=None,

17

autospec=None,

18

new_callable=None,

19

unsafe: bool = False,

20

**kwargs

21

):

22

"""

23

Temporarily replace an object during testing.

24

25

Parameters:

26

- target: String path to object to patch (e.g., 'module.function')

27

- new: Replacement object (DEFAULT creates appropriate mock)

28

- spec: Specification for created mock

29

- create: Create attribute if it doesn't exist

30

- spec_set: Like spec but restricts mock to only spec attributes

31

- autospec: Automatically create spec from target object

32

- new_callable: Factory for creating replacement object

33

- unsafe: Allow patching built-in or restricted objects

34

- **kwargs: Additional arguments for mock creation

35

36

Returns:

37

Context manager/decorator that yields the replacement object

38

"""

39

```

40

41

Usage examples:

42

43

```python

44

from mock import patch, Mock

45

46

# As decorator

47

@patch('module.function')

48

def test_function(mock_func):

49

mock_func.return_value = "mocked_result"

50

# Test code here

51

mock_func.assert_called_once()

52

53

# As context manager

54

def test_with_context():

55

with patch('module.function') as mock_func:

56

mock_func.return_value = "mocked_result"

57

# Test code here

58

mock_func.assert_called_once()

59

60

# Provide specific replacement

61

@patch('module.function', return_value="specific_result")

62

def test_with_specific_mock(mock_func):

63

# mock_func is configured with return_value

64

pass

65

66

# Create mock with specification

67

@patch('module.MyClass', autospec=True)

68

def test_with_autospec(mock_class):

69

# mock_class has same interface as MyClass

70

instance = mock_class()

71

instance.method.return_value = "test"

72

```

73

74

### Object Patching

75

76

Patch attributes of existing objects.

77

78

```python { .api }

79

def patch.object(

80

target,

81

attribute: str,

82

new=...,

83

spec=None,

84

create: bool = False,

85

spec_set=None,

86

autospec=None,

87

new_callable=None,

88

unsafe: bool = False,

89

**kwargs

90

):

91

"""

92

Patch an attribute of an existing object.

93

94

Parameters:

95

- target: Object containing the attribute to patch

96

- attribute: Name of attribute to patch

97

- Other parameters same as patch()

98

"""

99

```

100

101

Usage example:

102

103

```python

104

import os

105

from mock import patch

106

107

# Patch method of existing object

108

@patch.object(os, 'getcwd', return_value='/fake/path')

109

def test_getcwd(mock_getcwd):

110

assert os.getcwd() == '/fake/path'

111

mock_getcwd.assert_called_once()

112

113

# Patch with context manager

114

def test_patch_object():

115

with patch.object(os.path, 'exists', return_value=True) as mock_exists:

116

assert os.path.exists('/any/path') == True

117

mock_exists.assert_called_once_with('/any/path')

118

```

119

120

### Multiple Patching

121

122

Patch multiple attributes of the same object simultaneously.

123

124

```python { .api }

125

def patch.multiple(

126

target,

127

spec=None,

128

create: bool = False,

129

spec_set=None,

130

autospec=None,

131

new_callable=None,

132

unsafe: bool = False,

133

**kwargs

134

):

135

"""

136

Patch multiple attributes of a target object.

137

138

Parameters:

139

- target: Object to patch

140

- **kwargs: attribute_name=replacement pairs

141

- Other parameters same as patch()

142

143

Returns:

144

Dictionary mapping attribute names to mock objects

145

"""

146

```

147

148

Usage example:

149

150

```python

151

from mock import patch

152

153

# Patch multiple methods

154

@patch.multiple('os', getcwd=Mock(return_value='/fake'), getpid=Mock(return_value=123))

155

def test_multiple_patches(getcwd_mock, getpid_mock):

156

# getcwd_mock and getpid_mock are available

157

assert os.getcwd() == '/fake'

158

assert os.getpid() == 123

159

160

# With context manager - returns dict

161

def test_multiple_context():

162

with patch.multiple('os', getcwd=Mock(return_value='/fake'), getpid=Mock(return_value=123)) as mocks:

163

assert os.getcwd() == '/fake'

164

assert os.getpid() == 123

165

mocks['getcwd'].assert_called_once()

166

mocks['getpid'].assert_called_once()

167

```

168

169

### Patch Management

170

171

```python { .api }

172

def patch.stopall() -> None:

173

"""Stop all active patches created with start() method."""

174

```

175

176

Usage with manual patch management:

177

178

```python

179

from mock import patch

180

181

# Manual patch lifecycle

182

def test_manual_patches():

183

# Start patches manually

184

patch1 = patch('module.func1')

185

patch2 = patch('module.func2')

186

187

mock1 = patch1.start()

188

mock2 = patch2.start()

189

190

try:

191

# Test code here

192

mock1.return_value = "result1"

193

mock2.return_value = "result2"

194

195

# Your test assertions

196

pass

197

finally:

198

# Stop all patches

199

patch.stopall()

200

```

201

202

### Dictionary Patching

203

204

Temporarily modify dictionaries during testing.

205

206

```python { .api }

207

class patch.dict:

208

def __init__(

209

self,

210

in_dict,

211

values=(),

212

clear: bool = False,

213

**kwargs

214

) -> None:

215

"""

216

Temporarily modify a dictionary.

217

218

Parameters:

219

- in_dict: Dictionary to modify

220

- values: Values to set (dict or iterable of key-value pairs)

221

- clear: Clear dictionary before setting values

222

- **kwargs: Additional key-value pairs to set

223

"""

224

225

def __call__(self, func):

226

"""Use as decorator."""

227

228

def __enter__(self):

229

"""Use as context manager."""

230

231

def __exit__(self, *args):

232

"""Context manager cleanup."""

233

234

def start(self) -> None:

235

"""Start dictionary patching."""

236

237

def stop(self) -> None:

238

"""Stop dictionary patching."""

239

```

240

241

Usage examples:

242

243

```python

244

import os

245

from mock import patch

246

247

# Patch environment variables

248

@patch.dict(os.environ, {'TEST_VAR': 'test_value'})

249

def test_env_var():

250

assert os.environ['TEST_VAR'] == 'test_value'

251

252

# Context manager with clear

253

def test_env_clear():

254

with patch.dict(os.environ, {'ONLY_VAR': 'only_value'}, clear=True):

255

# os.environ only contains ONLY_VAR

256

assert os.environ == {'ONLY_VAR': 'only_value'}

257

# Original environment restored

258

259

# Patch custom dictionary

260

my_dict = {'existing': 'value'}

261

262

@patch.dict(my_dict, new_key='new_value')

263

def test_custom_dict():

264

assert my_dict['new_key'] == 'new_value'

265

assert my_dict['existing'] == 'value' # Original key preserved

266

```

267

268

### Advanced Patching Patterns

269

270

```python

271

# Patch with side effect

272

@patch('requests.get')

273

def test_with_side_effect(mock_get):

274

def side_effect(url):

275

if 'success' in url:

276

return Mock(status_code=200, json=lambda: {'data': 'success'})

277

else:

278

return Mock(status_code=404)

279

280

mock_get.side_effect = side_effect

281

282

# Test different responses based on input

283

response = requests.get('http://example.com/success')

284

assert response.status_code == 200

285

286

# Patch class and instance methods

287

@patch('module.MyClass')

288

def test_class_and_instance(mock_class):

289

# Configure class mock

290

mock_instance = Mock()

291

mock_class.return_value = mock_instance

292

mock_instance.method.return_value = "instance_result"

293

294

# Test code

295

obj = module.MyClass()

296

result = obj.method()

297

assert result == "instance_result"

298

299

mock_class.assert_called_once()

300

mock_instance.method.assert_called_once()

301

302

# Nested patching

303

@patch('outer.inner.function')

304

@patch('other.module.function')

305

def test_nested_patches(mock_other, mock_inner):

306

# Order matters - innermost decorator is first parameter

307

mock_inner.return_value = "inner_result"

308

mock_other.return_value = "other_result"

309

```

310

311

## Type Definitions

312

313

```python { .api }

314

# Patch object types (internal implementation details)

315

class _patch:

316

"""Internal patch implementation class."""

317

def __init__(self, getter, attribute: str, new, spec, create: bool, spec_set, autospec, new_callable, kwargs, *, unsafe: bool = False) -> None: ...

318

def __enter__(self): ...

319

def __exit__(self, exc_type, exc_value, traceback) -> None: ...

320

def start(self): ...

321

def stop(self) -> None: ...

322

323

class _patch_dict:

324

"""Internal dictionary patch implementation class."""

325

def __init__(self, in_dict, values=(), clear: bool = False, **kwargs) -> None: ...

326

def __enter__(self): ...

327

def __exit__(self, *args) -> None: ...

328

def start(self) -> None: ...

329

def stop(self) -> None: ...

330

```