0
# Deep Mocking
1
2
Advanced mocking capabilities for nested objects and complex data structures with recursive type-safe mocking.
3
4
## Capabilities
5
6
### Deep Mock Function
7
8
Creates a deep mock proxy that recursively mocks nested objects and properties, maintaining type safety throughout the entire object hierarchy.
9
10
```typescript { .api }
11
/**
12
* Creates deep mock with function property support
13
* @param opts - Configuration options including function property support
14
* @param mockImplementation - Optional partial implementation
15
* @returns Deep mock proxy with function property support
16
*/
17
function mockDeep<T>(
18
opts: {
19
funcPropSupport?: true;
20
fallbackMockImplementation?: MockOpts['fallbackMockImplementation']
21
},
22
mockImplementation?: DeepPartial<T>
23
): DeepMockProxyWithFuncPropSupport<T>;
24
25
/**
26
* Creates standard deep mock proxy
27
* @param mockImplementation - Optional partial implementation
28
* @returns Deep mock proxy for nested object mocking
29
*/
30
function mockDeep<T>(mockImplementation?: DeepPartial<T>): DeepMockProxy<T>;
31
```
32
33
**Usage Examples:**
34
35
```typescript
36
import { mockDeep, DeepMockProxy } from "jest-mock-extended";
37
38
interface Database {
39
users: {
40
findById: (id: string) => Promise<User>;
41
create: (user: CreateUserData) => Promise<User>;
42
repository: {
43
query: (sql: string) => Promise<any[]>;
44
transaction: {
45
begin: () => Promise<void>;
46
commit: () => Promise<void>;
47
rollback: () => Promise<void>;
48
};
49
};
50
};
51
products: {
52
findAll: () => Promise<Product[]>;
53
findByCategory: (category: string) => Promise<Product[]>;
54
};
55
}
56
57
// Standard deep mocking
58
const database: DeepMockProxy<Database> = mockDeep<Database>();
59
60
// Set up nested expectations
61
database.users.findById.calledWith("123").mockResolvedValue({
62
id: "123",
63
name: "John Doe"
64
});
65
66
database.users.repository.query
67
.calledWith("SELECT * FROM users")
68
.mockResolvedValue([{ id: "123" }]);
69
70
// Deep mocking with function property support
71
const advancedDatabase = mockDeep<Database>({ funcPropSupport: true });
72
73
// Can mock both function calls and function properties
74
advancedDatabase.users.repository.calledWith("custom").mockReturnValue("result");
75
advancedDatabase.users.repository.query.calledWith("SELECT").mockResolvedValue([]);
76
```
77
78
### DeepMockProxy Type
79
80
Type definition for deep mock proxies that recursively applies mocking to nested object properties.
81
82
```typescript { .api }
83
/**
84
* Deep mock proxy type for recursive mocking of nested objects
85
*/
86
type DeepMockProxy<T> = _DeepMockProxy<T> & T;
87
88
type _DeepMockProxy<T> = {
89
[K in keyof T]: T[K] extends FunctionLike
90
? T[K] & CalledWithMock<T[K]>
91
: T[K] & _DeepMockProxy<T[K]>;
92
};
93
```
94
95
**Usage Examples:**
96
97
```typescript
98
import { mockDeep, DeepMockProxy } from "jest-mock-extended";
99
100
interface ApiClient {
101
auth: {
102
login: (credentials: LoginCredentials) => Promise<AuthToken>;
103
logout: () => Promise<void>;
104
refresh: (token: string) => Promise<AuthToken>;
105
};
106
data: {
107
users: {
108
get: (id: string) => Promise<User>;
109
list: (params: ListParams) => Promise<User[]>;
110
};
111
posts: {
112
get: (id: string) => Promise<Post>;
113
create: (post: CreatePost) => Promise<Post>;
114
};
115
};
116
}
117
118
const apiClient: DeepMockProxy<ApiClient> = mockDeep<ApiClient>();
119
120
// All nested properties are automatically mocked
121
apiClient.auth.login.mockResolvedValue({ token: "abc123" });
122
apiClient.data.users.get.calledWith("user1").mockResolvedValue({ id: "user1" });
123
apiClient.data.posts.list.mockResolvedValue([]);
124
```
125
126
### DeepMockProxyWithFuncPropSupport Type
127
128
Extended deep mock proxy that supports both function calls and function properties, useful for objects that have functions with additional function properties.
129
130
```typescript { .api }
131
/**
132
* Deep mock proxy with support for function properties
133
*/
134
type DeepMockProxyWithFuncPropSupport<T> = _DeepMockProxyWithFuncPropSupport<T> & T;
135
136
type _DeepMockProxyWithFuncPropSupport<T> = {
137
[K in keyof T]: T[K] extends FunctionLike
138
? CalledWithMock<T[K]> & DeepMockProxy<T[K]>
139
: DeepMockProxy<T[K]>;
140
};
141
```
142
143
**Usage Examples:**
144
145
```typescript
146
import { mockDeep } from "jest-mock-extended";
147
148
interface Logger {
149
log: {
150
(message: string): void;
151
error: (error: Error) => void;
152
warn: (warning: string) => void;
153
debug: {
154
(message: string): void;
155
verbose: (details: any) => void;
156
};
157
};
158
}
159
160
// Enable function property support
161
const logger = mockDeep<Logger>({ funcPropSupport: true });
162
163
// Mock the main function
164
logger.log.calledWith("info message").mockReturnValue(undefined);
165
166
// Mock function properties
167
logger.log.error.calledWith(expect.any(Error)).mockReturnValue(undefined);
168
logger.log.debug.calledWith("debug info").mockReturnValue(undefined);
169
logger.log.debug.verbose.calledWith(expect.any(Object)).mockReturnValue(undefined);
170
171
// Test usage
172
logger.log("info message");
173
logger.log.error(new Error("test error"));
174
logger.log.debug("debug info");
175
logger.log.debug.verbose({ details: "verbose logging" });
176
```
177
178
### Deep Mock with Fallback Implementation
179
180
Deep mocking with fallback implementation for handling unmocked function calls.
181
182
**Usage Examples:**
183
184
```typescript
185
import { mockDeep } from "jest-mock-extended";
186
187
interface ComplexService {
188
cache: {
189
get: (key: string) => any;
190
set: (key: string, value: any) => void;
191
nested: {
192
clear: () => void;
193
stats: () => { hits: number; misses: number };
194
};
195
};
196
}
197
198
// Deep mock with strict fallback
199
const service = mockDeep<ComplexService>({
200
fallbackMockImplementation: () => {
201
throw new Error("Please add expected return value using calledWith");
202
}
203
});
204
205
// Set up specific expectations
206
service.cache.get.calledWith("user:123").mockReturnValue({ name: "John" });
207
service.cache.nested.stats.mockReturnValue({ hits: 10, misses: 2 });
208
209
// These will work
210
expect(service.cache.get("user:123")).toEqual({ name: "John" });
211
expect(service.cache.nested.stats()).toEqual({ hits: 10, misses: 2 });
212
213
// This will throw the fallback error
214
expect(() => service.cache.get("unmocked:key")).toThrow("Please add expected return value");
215
```