or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

argument-matching.mdbasic-mocking.mddeep-mocking.mdindex.mdmatchers.mdutilities.md
tile.json

argument-matching.mddocs/

0

# Argument Matching

1

2

Sophisticated argument matching system with calledWith() extension for creating expectations based on specific argument patterns.

3

4

## Capabilities

5

6

### CalledWith Extension

7

8

The calledWith method allows creating argument-specific expectations on mock functions, enabling precise behavior definition based on input parameters.

9

10

```typescript { .api }

11

/**

12

* Creates argument-specific expectation for mock function calls

13

* @param args - Expected arguments that can be literal values or matchers

14

* @returns Jest mock instance for chaining additional expectations

15

*/

16

calledWith(...args: [...MatchersOrLiterals<Parameters<T>>]): jest.Mock<T>;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { mock, any, anyString, anyNumber } from "jest-mock-extended";

23

24

interface UserService {

25

updateUser: (id: string, data: UserData, options?: UpdateOptions) => Promise<User>;

26

sendNotification: (userId: string, message: string, priority: number) => void;

27

}

28

29

const userService = mock<UserService>();

30

31

// Literal argument matching

32

userService.updateUser

33

.calledWith("user123", { name: "John" }, { validate: true })

34

.mockResolvedValue({ id: "user123", name: "John" });

35

36

// Mixed literal and matcher arguments

37

userService.updateUser

38

.calledWith("admin", any(), { admin: true })

39

.mockResolvedValue({ id: "admin", name: "Administrator" });

40

41

// Matcher-only arguments

42

userService.sendNotification

43

.calledWith(anyString(), anyString(), anyNumber())

44

.mockReturnValue(undefined);

45

46

// Multiple expectations for same function

47

userService.updateUser

48

.calledWith(anyString(), { status: "inactive" }, any())

49

.mockRejectedValue(new Error("Cannot update inactive user"));

50

```

51

52

### Matcher Arguments

53

54

Arguments in calledWith can be literal values or matcher objects that implement asymmetric matching patterns.

55

56

```typescript { .api }

57

/**

58

* Type defining arguments that can be either literal values or matcher objects

59

*/

60

type MatchersOrLiterals<Y extends any[]> = {

61

[K in keyof Y]: MatcherLike<Y[K]> | Y[K]

62

};

63

64

/**

65

* Interface for matcher objects that implement Jest asymmetric matcher protocol

66

*/

67

interface MatcherLike<T> {

68

asymmetricMatch(other: unknown): boolean;

69

toString(): string;

70

getExpectedType?(): string;

71

toAsymmetricMatcher?(): string;

72

}

73

```

74

75

**Usage Examples:**

76

77

```typescript

78

import { mock, any, anyString, anyObject, isA, arrayIncludes } from "jest-mock-extended";

79

80

interface DataProcessor {

81

processItems: (items: Item[], config: ProcessConfig) => ProcessResult;

82

validateInput: (data: any, schema: ValidationSchema) => boolean;

83

}

84

85

const processor = mock<DataProcessor>();

86

87

// Complex matcher combinations

88

processor.processItems

89

.calledWith(

90

arrayIncludes({ type: "premium" }), // Array must include premium item

91

{

92

strict: true,

93

timeout: anyNumber(),

94

filters: anyObject()

95

}

96

)

97

.mockReturnValue({ success: true, processedCount: 5 });

98

99

// Class instance matching

100

class CustomError extends Error {

101

constructor(public code: number, message: string) {

102

super(message);

103

}

104

}

105

106

processor.validateInput

107

.calledWith(any(), isA(ValidationSchema))

108

.mockReturnValue(true);

109

```

110

111

### CalledWith Function Creator

112

113

Creates a Jest mock function with calledWith extension functionality, providing low-level access to the argument matching system.

114

115

```typescript { .api }

116

/**

117

* Creates a Jest mock function with calledWith extension

118

* @param param - Destructured configuration parameter with fallback implementation

119

* @returns Mock function with argument-specific expectation capabilities

120

*/

121

const calledWithFn: <T extends FunctionLike>({

122

fallbackMockImplementation,

123

}?: { fallbackMockImplementation?: T }) => CalledWithMock<T>;

124

```

125

126

**Usage Examples:**

127

128

```typescript

129

import { calledWithFn, anyString, any } from "jest-mock-extended";

130

131

type ApiFunction = (method: string, url: string, data?: any) => Promise<Response>;

132

133

// Create mock function with calledWith extension

134

const apiFunc = calledWithFn<ApiFunction>({

135

fallbackMockImplementation: () => Promise.reject(new Error("Unmocked call"))

136

});

137

138

// Set up argument-specific expectations

139

apiFunc.calledWith("GET", anyString(), undefined)

140

.mockResolvedValue(new Response("GET success"));

141

142

apiFunc.calledWith("POST", "/api/users", any())

143

.mockResolvedValue(new Response("POST success"));

144

145

// Test the mock function

146

expect(await apiFunc("GET", "/api/data")).resolves.toBeDefined();

147

expect(await apiFunc("POST", "/api/users", { name: "John" })).resolves.toBeDefined();

148

149

// Unmocked calls will use fallback implementation

150

expect(apiFunc("DELETE", "/api/users/1")).rejects.toThrow("Unmocked call");

151

```

152

153

### Function Mock Creation

154

155

Standalone function mock creation with calledWith functionality for testing individual functions.

156

157

```typescript { .api }

158

/**

159

* Creates a Jest function mock with calledWith extension

160

* @returns Typed mock function with argument matching capabilities

161

*/

162

function mockFn<T extends FunctionLike>(): CalledWithMock<T> & T;

163

```

164

165

**Usage Examples:**

166

167

```typescript

168

import { mockFn, anyString, any } from "jest-mock-extended";

169

170

// Type definition for the function

171

type ApiCall = (

172

method: "GET" | "POST" | "PUT" | "DELETE",

173

url: string,

174

data?: any

175

) => Promise<ApiResponse>;

176

177

// Create typed mock function

178

const apiCall = mockFn<ApiCall>();

179

180

// Set up method-specific behavior

181

apiCall

182

.calledWith("GET", anyString(), undefined)

183

.mockResolvedValue({ status: 200, data: {} });

184

185

apiCall

186

.calledWith("POST", "/users", any())

187

.mockResolvedValue({ status: 201, data: { id: "new-user" } });

188

189

apiCall

190

.calledWith("DELETE", anyString(), undefined)

191

.mockResolvedValue({ status: 204, data: null });

192

193

// Test the mock

194

expect(await apiCall("GET", "/users")).toEqual({ status: 200, data: {} });

195

expect(await apiCall("POST", "/users", { name: "John" })).toEqual({

196

status: 201,

197

data: { id: "new-user" }

198

});

199

200

// Verify call expectations

201

expect(apiCall).toHaveBeenCalledWith("GET", "/users", undefined);

202

expect(apiCall).toHaveBeenCalledWith("POST", "/users", { name: "John" });

203

```

204

205

### Advanced Argument Patterns

206

207

Complex argument matching patterns for sophisticated testing scenarios.

208

209

**Usage Examples:**

210

211

```typescript

212

import { mock, captor, matches, anyString, any } from "jest-mock-extended";

213

214

interface EventEmitter {

215

emit: (event: string, data: any) => void;

216

on: (event: string, handler: (data: any) => void) => void;

217

}

218

219

const emitter = mock<EventEmitter>();

220

221

// Argument capturing

222

const eventCaptor = captor<string>();

223

const dataCaptor = captor<any>();

224

225

emitter.emit.calledWith(eventCaptor, dataCaptor).mockReturnValue(undefined);

226

227

emitter.emit("user:created", { id: "123", name: "John" });

228

229

// Access captured values

230

expect(eventCaptor.value).toBe("user:created");

231

expect(dataCaptor.value).toEqual({ id: "123", name: "John" });

232

233

// Custom matcher with complex logic

234

const isValidEmail = matches<string>((email) =>

235

/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)

236

);

237

238

interface EmailValidator {

239

validate: (email: string, domain?: string) => boolean;

240

}

241

242

const validator = mock<EmailValidator>();

243

244

validator.validate

245

.calledWith(isValidEmail, anyString())

246

.mockReturnValue(true);

247

248

validator.validate

249

.calledWith(matches((email) => !email.includes("@")), any())

250

.mockReturnValue(false);

251

252

// Test validation

253

expect(validator.validate("user@example.com", "example.com")).toBe(true);

254

expect(validator.validate("invalid-email", "example.com")).toBe(false);

255

```