or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

async-mocking.mddocs/

0

# Async Mocking

1

2

Specialized mock class for testing asynchronous code with await-specific assertions and async-aware call tracking. AsyncMock provides comprehensive support for testing coroutines, async context managers, and async iterators with full type safety.

3

4

## Capabilities

5

6

### AsyncMock

7

8

Mock class specifically designed for testing asynchronous code with await tracking and async-specific assertion methods.

9

10

```python { .api }

11

class AsyncMock(Mock):

12

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

13

"""

14

Create an async mock that can be awaited and tracks await calls.

15

16

Inherits all Mock parameters and adds async-specific functionality.

17

"""

18

19

# Async assertion methods

20

def assert_awaited(self) -> None:

21

"""Assert the mock has been awaited at least once."""

22

23

def assert_awaited_once(self) -> None:

24

"""Assert the mock has been awaited exactly once."""

25

26

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

27

"""Assert the mock was last awaited with specified arguments."""

28

29

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

30

"""Assert the mock was awaited exactly once with specified arguments."""

31

32

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

33

"""Assert the mock was awaited with specified arguments at some point."""

34

35

def assert_has_awaits(self, calls, any_order: bool = False) -> None:

36

"""Assert the mock has been awaited with specified call sequence."""

37

38

def assert_not_awaited(self) -> None:

39

"""Assert the mock has never been awaited."""

40

41

def reset_mock(

42

self,

43

visited=None,

44

*,

45

return_value: bool = False,

46

side_effect: bool = False

47

) -> None:

48

"""Reset mock state including await tracking."""

49

50

# Async state attributes

51

await_count: int # Number of times mock was awaited

52

await_args: call | None # Arguments from last await

53

await_args_list: list[call] # All await arguments

54

55

# Function metadata for better integration

56

__name__: str

57

__defaults__: tuple[Any, ...]

58

__kwdefaults__: dict[str, Any]

59

__annotations__: dict[str, Any] | None

60

```

61

62

Usage examples:

63

64

```python

65

import asyncio

66

from mock import AsyncMock

67

68

# Basic async mock usage

69

async def test_async_function():

70

async_mock = AsyncMock(return_value="async_result")

71

72

# Await the mock

73

result = await async_mock("arg1", key="value")

74

assert result == "async_result"

75

76

# Assert await behavior

77

async_mock.assert_awaited_once_with("arg1", key="value")

78

assert async_mock.await_count == 1

79

80

# Mock async context manager

81

async def test_async_context_manager():

82

async_mock = AsyncMock()

83

async_mock.__aenter__.return_value = "context_value"

84

async_mock.__aexit__.return_value = None

85

86

async with async_mock as ctx:

87

assert ctx == "context_value"

88

89

async_mock.__aenter__.assert_awaited_once()

90

async_mock.__aexit__.assert_awaited_once()

91

92

# Mock async iterator

93

async def test_async_iterator():

94

async_mock = AsyncMock()

95

async_mock.__aiter__.return_value = async_mock

96

async_mock.__anext__.side_effect = ["item1", "item2", StopAsyncIteration]

97

98

items = []

99

async for item in async_mock:

100

items.append(item)

101

102

assert items == ["item1", "item2"]

103

async_mock.__aiter__.assert_called_once()

104

```

105

106

### Async Side Effects

107

108

AsyncMock supports both synchronous and asynchronous side effects:

109

110

```python

111

# Async side effect function

112

async def async_side_effect(*args, **kwargs):

113

await asyncio.sleep(0.1)

114

return f"processed: {args}"

115

116

async_mock = AsyncMock(side_effect=async_side_effect)

117

result = await async_mock("test")

118

assert result == "processed: ('test',)"

119

120

# Exception side effect

121

async_mock = AsyncMock(side_effect=ValueError("async error"))

122

try:

123

await async_mock()

124

except ValueError as e:

125

assert str(e) == "async error"

126

127

# Multiple return values

128

async_mock = AsyncMock(side_effect=["first", "second", "third"])

129

assert await async_mock() == "first"

130

assert await async_mock() == "second"

131

assert await async_mock() == "third"

132

```

133

134

### Patching Async Functions

135

136

AsyncMock integrates seamlessly with the patching system:

137

138

```python

139

from mock import patch, AsyncMock

140

141

# Patch async function

142

@patch('module.async_function', new_callable=AsyncMock)

143

async def test_with_async_patch(mock_async_func):

144

mock_async_func.return_value = "mocked_result"

145

146

# Test code that calls module.async_function

147

result = await module.async_function("arg")

148

assert result == "mocked_result"

149

mock_async_func.assert_awaited_once_with("arg")

150

151

# Context manager patching

152

async def test_with_context_patch():

153

with patch('module.async_function', new_callable=AsyncMock) as mock_func:

154

mock_func.return_value = "mocked"

155

result = await module.async_function()

156

assert result == "mocked"

157

```

158

159

### Async Mock Specifications

160

161

AsyncMock supports specification-based mocking for async objects:

162

163

```python

164

class AsyncService:

165

async def fetch_data(self, query: str) -> dict:

166

# Real implementation

167

pass

168

169

async def process_data(self, data: dict) -> str:

170

# Real implementation

171

pass

172

173

# Create mock with async specification

174

async_service_mock = AsyncMock(spec=AsyncService)

175

async_service_mock.fetch_data.return_value = {"result": "data"}

176

async_service_mock.process_data.return_value = "processed"

177

178

# Use the mock

179

data = await async_service_mock.fetch_data("query")

180

result = await async_service_mock.process_data(data)

181

182

async_service_mock.fetch_data.assert_awaited_once_with("query")

183

async_service_mock.process_data.assert_awaited_once_with({"result": "data"})

184

```

185

186

## Type Definitions

187

188

```python { .api }

189

# Async-specific call tracking extends regular call functionality

190

# call objects work the same for both sync and async contexts

191

192

# Coroutine function type checking (from backports)

193

def iscoroutinefunction(func) -> bool:

194

"""Check if a function is a coroutine function."""

195

196

# Async test case base class (from backports)

197

class IsolatedAsyncioTestCase:

198

"""Base class for async test cases with isolated event loops."""

199

```