or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmock-controller.mdrequest-response.mdutilities.md

utilities.mddocs/

0

# Utility Functions

1

2

xhr-mock provides several utility functions for advanced mocking scenarios including delays, one-time responses, response sequences, and request proxying to real servers.

3

4

## Capabilities

5

6

### Once Function

7

8

Creates a mock handler that only responds to the first request, then becomes inactive.

9

10

```typescript { .api }

11

/**

12

* Create a mock that only responds once

13

* @param mock - Mock object or function to use for the single response

14

* @returns MockFunction that responds only to the first matching request

15

*/

16

function once(mock: MockFunction | MockObject): MockFunction;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import mock, { once } from 'xhr-mock';

23

24

// One-time response with object

25

mock.get('/api/special-offer', once({

26

status: 200,

27

body: JSON.stringify({ offer: 'Limited time 50% off!' })

28

}));

29

30

// One-time response with function

31

mock.post('/api/trial-signup', once((req, res) => {

32

const email = JSON.parse(req.body()).email;

33

return res.status(201).body(JSON.stringify({

34

message: 'Trial activated',

35

email

36

}));

37

}));

38

39

// After the first request, subsequent requests will not match this handler

40

```

41

42

### Delay Function

43

44

Adds a delay to mock responses to simulate network latency or slow servers.

45

46

```typescript { .api }

47

/**

48

* Add delay to mock responses

49

* @param mock - Mock object or function to delay

50

* @param ms - Delay in milliseconds (default: 1500)

51

* @returns MockFunction that responds after the specified delay

52

*/

53

function delay(mock: MockFunction | MockObject, ms?: number): MockFunction;

54

```

55

56

**Usage Examples:**

57

58

```typescript

59

import mock, { delay } from 'xhr-mock';

60

61

// Default delay (1500ms)

62

mock.get('/api/slow-endpoint', delay({

63

status: 200,

64

body: JSON.stringify({ data: 'This took a while...' })

65

}));

66

67

// Custom delay (3 seconds)

68

mock.post('/api/upload', delay({

69

status: 201,

70

body: JSON.stringify({ message: 'Upload complete' })

71

}, 3000));

72

73

// Delay with function

74

mock.get('/api/processing', delay((req, res) => {

75

return res.status(200).body(JSON.stringify({

76

status: 'processed',

77

timestamp: Date.now()

78

}));

79

}, 2000));

80

```

81

82

### Sequence Function

83

84

Returns different responses for consecutive requests to the same endpoint.

85

86

```typescript { .api }

87

/**

88

* Return different responses for consecutive requests

89

* @param mocks - Array of mock objects or functions to use in sequence

90

* @returns MockFunction that cycles through the provided mocks

91

*/

92

function sequence(mocks: (MockFunction | MockObject)[]): MockFunction;

93

```

94

95

**Usage Examples:**

96

97

```typescript

98

import mock, { sequence } from 'xhr-mock';

99

100

// Different status codes for each request

101

mock.get('/api/flaky-service', sequence([

102

{ status: 200, body: 'Success on first try' },

103

{ status: 500, body: 'Server error on second try' },

104

{ status: 200, body: 'Success on third try' }

105

]));

106

107

// Mixed objects and functions

108

mock.post('/api/batch-process', sequence([

109

(req, res) => res.status(202).body('Processing started'),

110

{ status: 202, body: 'Still processing...' },

111

{ status: 200, body: 'Processing complete' }

112

// After the third request, no more responses (undefined returned)

113

]));

114

115

// First request gets first response, second gets second, etc.

116

// After all responses are used, subsequent requests get no response

117

```

118

119

### Proxy Function

120

121

Forwards unhandled requests to real servers, allowing you to mock some endpoints while letting others pass through.

122

123

```typescript { .api }

124

/**

125

* Proxy unhandled requests to real servers

126

* @param req - MockRequest object representing the incoming request

127

* @param res - MockResponse object to populate with the real response

128

* @returns Promise resolving to MockResponse with real server data

129

*/

130

function proxy(req: MockRequest, res: MockResponse): Promise<MockResponse>;

131

```

132

133

**Usage Examples:**

134

135

```typescript

136

import mock, { proxy } from 'xhr-mock';

137

138

mock.setup();

139

140

// Mock specific endpoints

141

mock.post('/api/auth/login', {

142

status: 200,

143

body: JSON.stringify({ token: 'fake-jwt-token' })

144

});

145

146

// Proxy all other requests to real servers

147

mock.use(proxy);

148

149

// This request will be mocked

150

fetch('/api/auth/login', {

151

method: 'POST',

152

body: JSON.stringify({ username: 'test', password: 'test' })

153

});

154

155

// This request will be proxied to the real server

156

fetch('https://api.github.com/users/octocat');

157

```

158

159

**Advanced Proxy Usage:**

160

161

```typescript

162

// Selective proxying with custom logic

163

mock.use((req, res) => {

164

const url = req.url();

165

166

// Mock localhost requests

167

if (url.host === 'localhost') {

168

return res.status(200).body('Mocked localhost response');

169

}

170

171

// Proxy external requests

172

if (url.host.includes('api.external.com')) {

173

return proxy(req, res);

174

}

175

176

// Default response for everything else

177

return res.status(404).body('Not found');

178

});

179

```

180

181

## Combining Utilities

182

183

Utilities can be combined to create complex mocking scenarios:

184

185

```typescript

186

import mock, { once, delay, sequence } from 'xhr-mock';

187

188

// One-time delayed response

189

mock.get('/api/setup', once(delay({

190

status: 200,

191

body: JSON.stringify({ initialized: true })

192

}, 2000)));

193

194

// Delayed sequence

195

mock.get('/api/polling', delay(sequence([

196

{ status: 202, body: 'Processing...' },

197

{ status: 202, body: 'Still processing...' },

198

{ status: 200, body: 'Complete!' }

199

]), 1000));

200

201

// Complex scenario: First request is delayed, subsequent requests are fast

202

let firstRequest = true;

203

mock.get('/api/cache-warmup', (req, res) => {

204

const response = res.status(200).body('Data loaded');

205

206

if (firstRequest) {

207

firstRequest = false;

208

return delay(() => response, 3000)(req, res);

209

}

210

211

return response;

212

});

213

```

214

215

## Error Simulation

216

217

Create realistic error scenarios for testing error handling:

218

219

```typescript

220

// Simulate network errors

221

mock.get('/api/unreliable', () => {

222

return Promise.reject(new Error('Network error'));

223

});

224

225

// Simulate timeouts (return a promise that never resolves)

226

mock.get('/api/timeout', () => {

227

return new Promise(() => {}); // Never resolves

228

});

229

230

// Then in your test setup:

231

const xhr = new XMLHttpRequest();

232

xhr.timeout = 1000; // 1 second timeout

233

xhr.ontimeout = () => console.log('Request timed out');

234

xhr.onerror = () => console.log('Network error occurred');

235

```

236

237

## Types

238

239

```typescript { .api }

240

type MockFunction = (

241

request: MockRequest,

242

response: MockResponse

243

) => undefined | MockResponse | Promise<undefined | MockResponse>;

244

245

interface MockObject {

246

status?: number;

247

reason?: string;

248

headers?: MockHeaders;

249

body?: any;

250

}

251

252

type MockHeaders = {[name: string]: string};

253

```