0
# Utilities
1
2
Mock management utilities for clearing, resetting, and configuring mock behavior globally.
3
4
## Capabilities
5
6
### Mock Clearing
7
8
Recursively clears all mock calls and instances while preserving configured expectations and return values.
9
10
```typescript { .api }
11
/**
12
* Recursively clears all mock calls and instances
13
* @param mock - Mock proxy to clear (can be nested)
14
*/
15
function mockClear(mock: MockProxy<any>): void;
16
```
17
18
**Usage Examples:**
19
20
```typescript
21
import { mock, mockClear, MockProxy } from "jest-mock-extended";
22
23
interface UserService {
24
getUser: (id: string) => Promise<User>;
25
updateUser: (id: string, data: UserData) => Promise<User>;
26
nested: {
27
cache: {
28
get: (key: string) => any;
29
set: (key: string, value: any) => void;
30
};
31
};
32
}
33
34
describe("UserService tests", () => {
35
let userService: MockProxy<UserService>;
36
37
beforeEach(() => {
38
userService = mock<UserService>();
39
40
// Set up expectations
41
userService.getUser.calledWith("123").mockResolvedValue({ id: "123", name: "John" });
42
userService.nested.cache.get.calledWith("user:123").mockReturnValue({ cached: true });
43
});
44
45
afterEach(() => {
46
// Clear all calls but keep expectations
47
mockClear(userService);
48
});
49
50
test("first test", async () => {
51
await userService.getUser("123");
52
userService.nested.cache.get("user:123");
53
54
expect(userService.getUser).toHaveBeenCalledTimes(1);
55
expect(userService.nested.cache.get).toHaveBeenCalledTimes(1);
56
});
57
58
test("second test", async () => {
59
// Calls were cleared, but expectations remain
60
expect(userService.getUser).toHaveBeenCalledTimes(0);
61
expect(userService.nested.cache.get).toHaveBeenCalledTimes(0);
62
63
// Expectations still work
64
const result = await userService.getUser("123");
65
expect(result).toEqual({ id: "123", name: "John" });
66
});
67
});
68
```
69
70
### Mock Resetting
71
72
Recursively resets all mock calls, instances, and return values, completely clearing all mock state.
73
74
```typescript { .api }
75
/**
76
* Recursively resets all mock calls, instances, and return values
77
* @param mock - Mock proxy to reset (can be nested)
78
*/
79
function mockReset(mock: MockProxy<any>): void;
80
```
81
82
**Usage Examples:**
83
84
```typescript
85
import { mock, mockReset, MockProxy } from "jest-mock-extended";
86
87
interface ApiClient {
88
request: (method: string, url: string) => Promise<any>;
89
auth: {
90
login: (credentials: LoginData) => Promise<AuthToken>;
91
logout: () => Promise<void>;
92
};
93
}
94
95
describe("ApiClient tests", () => {
96
let apiClient: MockProxy<ApiClient>;
97
98
beforeEach(() => {
99
apiClient = mock<ApiClient>();
100
});
101
102
test("test with fresh mock", () => {
103
// Set up expectations for this test
104
apiClient.request.calledWith("GET", "/users").mockResolvedValue([]);
105
apiClient.auth.login.mockResolvedValue({ token: "abc123" });
106
107
// Use the mock
108
expect(apiClient.request("GET", "/users")).resolves.toEqual([]);
109
expect(apiClient.auth.login({ username: "user", password: "pass" }))
110
.resolves.toEqual({ token: "abc123" });
111
});
112
113
test("test with completely reset mock", () => {
114
// Set up some expectations
115
apiClient.request.mockResolvedValue("initial");
116
apiClient.auth.logout.mockResolvedValue(undefined);
117
118
// Use the mock
119
expect(apiClient.request("POST", "/data")).resolves.toBe("initial");
120
121
// Completely reset the mock - clears all calls and expectations
122
mockReset(apiClient);
123
124
// Mock is now completely clean
125
expect(apiClient.request).toHaveBeenCalledTimes(0);
126
expect(apiClient.auth.logout).toHaveBeenCalledTimes(0);
127
128
// Need to set up new expectations
129
apiClient.request.calledWith("GET", "/fresh").mockResolvedValue("fresh data");
130
expect(apiClient.request("GET", "/fresh")).resolves.toBe("fresh data");
131
});
132
});
133
```
134
135
### Stub Creation
136
137
Creates a simple stub object that returns jest.fn() for any property access, useful for basic mocking scenarios.
138
139
```typescript { .api }
140
/**
141
* Creates a stub that returns jest.fn() for any property access
142
* @returns Stub object with dynamic jest.fn() properties
143
*/
144
function stub<T extends object>(): T;
145
```
146
147
**Usage Examples:**
148
149
```typescript
150
import { stub } from "jest-mock-extended";
151
152
interface Logger {
153
info: (message: string) => void;
154
warn: (message: string) => void;
155
error: (message: string) => void;
156
debug: (message: string) => void;
157
}
158
159
// Create a simple stub
160
const logger = stub<Logger>();
161
162
// All properties return jest.fn() automatically
163
logger.info("test message");
164
logger.error("error message");
165
166
// Can set up expectations like regular jest.fn()
167
logger.warn.mockImplementation((msg) => console.log(`WARN: ${msg}`));
168
169
// Verify calls
170
expect(logger.info).toHaveBeenCalledWith("test message");
171
expect(logger.error).toHaveBeenCalledWith("error message");
172
173
// Example usage in dependency injection
174
class UserService {
175
constructor(private logger: Logger) {}
176
177
createUser(userData: any) {
178
this.logger.info("Creating user");
179
// ... user creation logic
180
this.logger.info("User created successfully");
181
}
182
}
183
184
const userService = new UserService(stub<Logger>());
185
userService.createUser({ name: "John" });
186
187
// Verify logging calls were made
188
expect(userService['logger'].info).toHaveBeenCalledTimes(2);
189
```
190
191
### Global Configuration
192
193
System for configuring global mock behavior across your entire test suite.
194
195
```typescript { .api }
196
/**
197
* Global configuration interface for mock behavior
198
*/
199
interface GlobalConfig {
200
/** Properties to ignore when creating mock proxies */
201
ignoreProps?: ProxiedProperty[];
202
}
203
204
/**
205
* Configuration object for global mock settings
206
*/
207
const JestMockExtended: {
208
/** Default configuration object */
209
DEFAULT_CONFIG: GlobalConfig;
210
211
/**
212
* Configure global mock behavior
213
* @param config - Configuration options to apply globally
214
*/
215
configure: (config: GlobalConfig) => void;
216
217
/** Reset configuration to default values */
218
resetConfig: () => void;
219
};
220
221
type ProxiedProperty = string | number | symbol;
222
```
223
224
**Usage Examples:**
225
226
```typescript
227
import { JestMockExtended, mock } from "jest-mock-extended";
228
229
// Default configuration includes ignoring 'then' property for promise handling
230
interface AsyncService {
231
fetchData: () => Promise<any>;
232
processData: (data: any) => Promise<void>;
233
}
234
235
// Configure global settings before tests
236
beforeAll(() => {
237
JestMockExtended.configure({
238
ignoreProps: ['then', 'catch', 'finally', 'constructor']
239
});
240
});
241
242
afterAll(() => {
243
// Reset to defaults after tests
244
JestMockExtended.resetConfig();
245
});
246
247
test("mock with global config", () => {
248
const service = mock<AsyncService>();
249
250
// 'then' property is ignored and returns undefined
251
expect(service.then).toBeUndefined();
252
253
// Regular mocking still works
254
service.fetchData.mockResolvedValue({ data: "test" });
255
expect(service.fetchData()).resolves.toEqual({ data: "test" });
256
});
257
258
// Example: Ignoring specific framework properties
259
interface ReactComponent {
260
render: () => JSX.Element;
261
componentDidMount: () => void;
262
setState: (state: any) => void;
263
// React internals that shouldn't be mocked
264
_reactInternalFiber?: any;
265
_reactInternalInstance?: any;
266
}
267
268
beforeEach(() => {
269
JestMockExtended.configure({
270
ignoreProps: [
271
'then', // Default for promises
272
'_reactInternalFiber',
273
'_reactInternalInstance',
274
'$$typeof'
275
]
276
});
277
});
278
279
test("React component mock", () => {
280
const component = mock<ReactComponent>();
281
282
// Internal React properties are ignored
283
expect(component._reactInternalFiber).toBeUndefined();
284
expect(component._reactInternalInstance).toBeUndefined();
285
286
// Regular component methods work
287
component.render.mockReturnValue(<div>Test</div>);
288
component.componentDidMount.mockImplementation(() => {});
289
290
expect(component.render()).toEqual(<div>Test</div>);
291
});
292
293
// Temporary configuration changes
294
test("temporary config override", () => {
295
// Save current config
296
const originalConfig = JestMockExtended.DEFAULT_CONFIG;
297
298
// Apply temporary config
299
JestMockExtended.configure({
300
ignoreProps: ['customProperty', 'tempProp']
301
});
302
303
const testMock = mock<{ customProperty: string; normalProp: string }>();
304
305
expect(testMock.customProperty).toBeUndefined();
306
expect(typeof testMock.normalProp).toBe('function'); // Mock function created
307
308
// Restore original config
309
JestMockExtended.resetConfig();
310
});
311
```