or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

utilities.mddocs/

0

# Utilities

1

2

Helper functions and specialized mock classes for common testing scenarios. These utilities provide enhanced functionality for automatic spec creation, file mocking, property mocking, and mock validation to streamline test development.

3

4

## Capabilities

5

6

### Automatic Specification

7

8

Automatically create mocks that match the interface of target objects.

9

10

```python { .api }

11

def create_autospec(

12

spec,

13

spec_set: bool = False,

14

instance: bool = False,

15

_parent=None,

16

_name=None,

17

*,

18

unsafe: bool = False,

19

**kwargs

20

):

21

"""

22

Create a mock with automatic specification based on another object.

23

24

Parameters:

25

- spec: Object to create specification from

26

- spec_set: If True, attempting to access non-existent attributes raises AttributeError

27

- instance: If True, mock represents an instance rather than the class itself

28

- unsafe: Allow mocking of built-in types and methods

29

- **kwargs: Additional arguments passed to Mock constructor

30

31

Returns:

32

Mock object that matches the interface of spec

33

"""

34

```

35

36

Usage examples:

37

38

```python

39

from mock import create_autospec

40

41

class Calculator:

42

def add(self, a: int, b: int) -> int:

43

return a + b

44

45

def multiply(self, a: int, b: int) -> int:

46

return a * b

47

48

# Create mock with automatic spec

49

calc_mock = create_autospec(Calculator, spec_set=True)

50

51

# Mock has same interface as Calculator

52

calc_mock.add.return_value = 10

53

result = calc_mock.add(5, 3)

54

assert result == 10

55

56

# Accessing non-existent method raises AttributeError (with spec_set=True)

57

try:

58

calc_mock.nonexistent_method()

59

except AttributeError:

60

pass # Expected behavior

61

62

# Create instance mock

63

calc_instance_mock = create_autospec(Calculator, instance=True)

64

calc_instance_mock.add.return_value = 15

65

assert calc_instance_mock.add(7, 8) == 15

66

67

# Function autospec

68

def original_function(x: int, y: str = "default") -> str:

69

return f"{y}: {x}"

70

71

func_mock = create_autospec(original_function)

72

func_mock.return_value = "mocked result"

73

result = func_mock(42, y="test")

74

assert result == "mocked result"

75

func_mock.assert_called_once_with(42, y="test")

76

```

77

78

### File Mocking

79

80

Create mock file-like objects for testing file operations.

81

82

```python { .api }

83

def mock_open(mock=None, read_data: str = ""):

84

"""

85

Create a mock that simulates file operations.

86

87

Parameters:

88

- mock: Existing mock to configure (creates new MagicMock if None)

89

- read_data: String data that read() and readline() methods will return

90

91

Returns:

92

Mock object that behaves like a file

93

"""

94

```

95

96

Usage examples:

97

98

```python

99

from mock import mock_open, patch

100

101

# Basic file mocking

102

def test_file_reading():

103

with patch('builtins.open', mock_open(read_data="file content")) as mock_file:

104

with open('test.txt', 'r') as f:

105

content = f.read()

106

107

assert content == "file content"

108

mock_file.assert_called_once_with('test.txt', 'r')

109

110

# Multi-line file content

111

def test_multiline_file():

112

file_content = "line 1\nline 2\nline 3"

113

with patch('builtins.open', mock_open(read_data=file_content)):

114

with open('test.txt', 'r') as f:

115

lines = f.readlines()

116

117

assert lines == ["line 1\n", "line 2\n", "line 3"]

118

119

# Test file writing

120

def test_file_writing():

121

with patch('builtins.open', mock_open()) as mock_file:

122

with open('test.txt', 'w') as f:

123

f.write("test content")

124

125

mock_file.assert_called_once_with('test.txt', 'w')

126

mock_file().write.assert_called_once_with("test content")

127

128

# Complex file operations

129

def test_file_operations():

130

mock_file_data = mock_open(read_data="initial content")

131

132

with patch('builtins.open', mock_file_data):

133

# Test reading

134

with open('file.txt', 'r') as f:

135

content = f.read()

136

assert content == "initial content"

137

138

# Test writing

139

with open('file.txt', 'w') as f:

140

f.write("new content")

141

142

# Verify calls

143

mock_file_data.assert_any_call('file.txt', 'r')

144

mock_file_data.assert_any_call('file.txt', 'w')

145

```

146

147

### Property Mocking

148

149

Mock property attributes and descriptors.

150

151

```python { .api }

152

class PropertyMock(Mock):

153

def __init__(self, *args, **kwargs) -> None:

154

"""Create a mock for property objects."""

155

156

def __get__(self, obj, obj_type=None):

157

"""Descriptor get method - called when property is accessed."""

158

159

def __set__(self, obj, value) -> None:

160

"""Descriptor set method - called when property is assigned."""

161

```

162

163

Usage examples:

164

165

```python

166

from mock import PropertyMock, patch

167

168

class MyClass:

169

@property

170

def value(self):

171

return self._value

172

173

@value.setter

174

def value(self, val):

175

self._value = val

176

177

# Mock property directly

178

def test_property_mock():

179

obj = MyClass()

180

181

with patch.object(MyClass, 'value', new_callable=PropertyMock) as mock_prop:

182

mock_prop.return_value = "mocked_value"

183

184

# Test property access

185

assert obj.value == "mocked_value"

186

mock_prop.__get__.assert_called_once()

187

188

# Test property assignment

189

obj.value = "new_value"

190

mock_prop.__set__.assert_called_once_with(obj, "new_value")

191

192

# Property with side effects

193

def test_property_side_effect():

194

obj = MyClass()

195

196

with patch.object(MyClass, 'value', new_callable=PropertyMock) as mock_prop:

197

# Different behavior on successive calls

198

mock_prop.side_effect = ["first", "second", "third"]

199

200

assert obj.value == "first"

201

assert obj.value == "second"

202

assert obj.value == "third"

203

204

# Mock computed property

205

class ComputedClass:

206

@property

207

def computed(self):

208

return len(self.data) * 2

209

210

def test_computed_property():

211

obj = ComputedClass()

212

213

with patch.object(ComputedClass, 'computed', new_callable=PropertyMock) as mock_prop:

214

mock_prop.return_value = 42

215

assert obj.computed == 42

216

mock_prop.__get__.assert_called_once()

217

```

218

219

### Mock Sealing

220

221

Prevent accidental attribute access on mocks.

222

223

```python { .api }

224

def seal(mock) -> None:

225

"""

226

Seal a mock to prevent creation of new attributes.

227

228

Parameters:

229

- mock: Mock object to seal

230

231

After sealing, accessing non-existent attributes raises AttributeError.

232

"""

233

```

234

235

Usage examples:

236

237

```python

238

from mock import Mock, seal

239

240

# Basic sealing

241

def test_mock_sealing():

242

mock_obj = Mock()

243

mock_obj.existing_attr = "value"

244

245

# Seal the mock

246

seal(mock_obj)

247

248

# Existing attributes still work

249

assert mock_obj.existing_attr == "value"

250

251

# New attributes raise AttributeError

252

try:

253

_ = mock_obj.new_attr

254

assert False, "Should have raised AttributeError"

255

except AttributeError:

256

pass # Expected

257

258

# Sealing prevents typos in tests

259

def test_seal_prevents_typos():

260

mock_service = Mock()

261

mock_service.process_data = Mock(return_value="result")

262

263

seal(mock_service)

264

265

# This works

266

result = mock_service.process_data("input")

267

assert result == "result"

268

269

# This would catch typos at runtime

270

try:

271

mock_service.proces_data("input") # Typo in method name

272

assert False, "Should catch typo"

273

except AttributeError:

274

pass # Typo caught

275

276

# Sealing with autospec

277

def test_seal_with_autospec():

278

from mock import create_autospec

279

280

class Service:

281

def method_one(self): pass

282

def method_two(self): pass

283

284

mock_service = create_autospec(Service)

285

seal(mock_service)

286

287

# Spec methods work

288

mock_service.method_one.return_value = "one"

289

mock_service.method_two.return_value = "two"

290

291

# Non-spec methods raise AttributeError

292

try:

293

mock_service.method_three()

294

assert False, "Should not allow non-spec method"

295

except AttributeError:

296

pass

297

```

298

299

### Sentinel Objects

300

301

Create unique sentinel values for testing.

302

303

```python { .api }

304

# Sentinel factory

305

sentinel: object # Factory for creating unique sentinel objects

306

307

# Individual sentinel object

308

class _SentinelObject:

309

def __init__(self, name: str) -> None: ...

310

name: str

311

312

# Usage: sentinel.ATTRIBUTE_NAME creates unique sentinel

313

```

314

315

Usage examples:

316

317

```python

318

from mock import sentinel

319

320

# Create unique sentinels

321

MISSING = sentinel.MISSING

322

EMPTY = sentinel.EMPTY

323

DEFAULT_VALUE = sentinel.DEFAULT_VALUE

324

325

def process_value(value=MISSING):

326

if value is MISSING:

327

return "no value provided"

328

elif value is EMPTY:

329

return "empty value"

330

else:

331

return f"value: {value}"

332

333

# Test with sentinels

334

def test_with_sentinels():

335

assert process_value() == "no value provided"

336

assert process_value(EMPTY) == "empty value"

337

assert process_value("real") == "value: real"

338

339

# Sentinels are unique

340

assert MISSING is not EMPTY

341

assert MISSING is not DEFAULT_VALUE

342

assert EMPTY is not DEFAULT_VALUE

343

344

# But same name creates same sentinel

345

assert sentinel.MISSING is MISSING

346

```

347

348

### Special Matching Objects

349

350

```python { .api }

351

# Match any value in assertions

352

ANY: object # Always equals any other object

353

354

# Default value marker

355

DEFAULT: object # Marker for default behavior in mocks

356

```

357

358

Usage examples:

359

360

```python

361

from mock import Mock, ANY, DEFAULT, call

362

363

# ANY matches anything

364

def test_any_matching():

365

mock_func = Mock()

366

mock_func("arg1", "arg2")

367

368

# These all pass

369

mock_func.assert_called_with("arg1", ANY)

370

mock_func.assert_called_with(ANY, "arg2")

371

mock_func.assert_called_with(ANY, ANY)

372

373

# ANY in call lists

374

def test_any_in_calls():

375

mock_func = Mock()

376

mock_func("first", 1)

377

mock_func("second", 2)

378

379

expected_calls = [

380

call("first", ANY),

381

call(ANY, 2)

382

]

383

mock_func.assert_has_calls(expected_calls)

384

385

# DEFAULT in side effects

386

def test_default_marker():

387

mock_func = Mock()

388

mock_func.side_effect = ["first", DEFAULT, "third"]

389

mock_func.return_value = "default_return"

390

391

assert mock_func() == "first"

392

assert mock_func() == "default_return" # DEFAULT uses return_value

393

assert mock_func() == "third"

394

```

395

396

## Type Definitions

397

398

```python { .api }

399

# Utility type definitions

400

class _SpecState:

401

"""Internal state for spec-based mocks."""

402

spec: Any

403

ids: Any

404

spec_set: Any

405

parent: Any

406

instance: Any

407

name: Any

408

409

class InvalidSpecError(Exception):

410

"""Raised when spec validation fails."""

411

```