or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdargument-capturing.mdbdd-testing.mdindex.mdjunit-integration.mdmatchers.mdmock-creation.mdstubbing.mdverification.md

matchers.mddocs/

0

# Argument Matching

1

2

Argument matchers provide flexible matching for method arguments during stubbing and verification. They allow you to specify patterns instead of exact values.

3

4

## Basic Matchers

5

6

### Any Matchers

7

8

```java { .api }

9

public static <T> T any();

10

public static <T> T any(Class<T> clazz);

11

public static <T> T anyObject(); // Deprecated, use any()

12

```

13

14

**Usage Examples:**

15

16

```java

17

// Match any object

18

when(mock.process(any())).thenReturn("result");

19

verify(mock).process(any());

20

21

// Match any object of specific type

22

when(mock.handle(any(String.class))).thenReturn(true);

23

when(mock.save(any(User.class))).thenReturn(user);

24

25

// Verify with type-specific matcher

26

verify(userService).save(any(User.class));

27

```

28

29

### Equality Matchers

30

31

```java { .api }

32

public static <T> T eq(T value);

33

public static <T> T same(T value);

34

public static <T> T refEq(T value, String... excludeFields);

35

```

36

37

**Usage Examples:**

38

39

```java

40

// Exact equality match

41

when(mock.get(eq("key"))).thenReturn("value");

42

verify(mock).process(eq(123));

43

44

// Same reference match

45

User user = new User();

46

when(mock.process(same(user))).thenReturn("processed");

47

48

// Reference equality with excluded fields

49

User expectedUser = new User("John", "john@example.com");

50

verify(userService).save(refEq(expectedUser, "id", "createdAt"));

51

```

52

53

### Null Matchers

54

55

```java { .api }

56

public static <T> T isNull();

57

public static <T> T isNotNull();

58

public static <T> T notNull(); // Deprecated, use isNotNull()

59

```

60

61

**Usage Examples:**

62

63

```java

64

// Match null values

65

when(service.process(isNull())).thenThrow(IllegalArgumentException.class);

66

67

// Match non-null values

68

when(service.process(isNotNull())).thenReturn("processed");

69

70

// Verification

71

verify(service).handle(isNull());

72

verify(service).save(isNotNull());

73

```

74

75

## String Matchers

76

77

```java { .api }

78

public static String anyString();

79

public static String contains(String substring);

80

public static String matches(String regex);

81

public static String endsWith(String suffix);

82

public static String startsWith(String prefix);

83

```

84

85

**Usage Examples:**

86

87

```java

88

// Any string

89

when(service.process(anyString())).thenReturn("default");

90

91

// String contains substring

92

when(service.findByName(contains("John"))).thenReturn(users);

93

verify(logger).log(contains("ERROR"));

94

95

// String matches regex

96

when(service.validate(matches("\\d{3}-\\d{2}-\\d{4}"))).thenReturn(true);

97

98

// String starts/ends with

99

when(service.getByPrefix(startsWith("user_"))).thenReturn(userData);

100

when(service.getByExtension(endsWith(".txt"))).thenReturn(textFiles);

101

```

102

103

## Numeric Matchers

104

105

```java { .api }

106

public static byte anyByte();

107

public static short anyShort();

108

public static int anyInt();

109

public static long anyLong();

110

public static float anyFloat();

111

public static double anyDouble();

112

public static boolean anyBoolean();

113

public static char anyChar();

114

```

115

116

**Usage Examples:**

117

118

```java

119

// Numeric type matchers

120

when(calculator.add(anyInt(), anyInt())).thenReturn(42);

121

when(service.processRate(anyDouble())).thenReturn(true);

122

when(service.isActive(anyBoolean())).thenReturn("status");

123

124

// Verification

125

verify(calculator).multiply(anyFloat(), anyFloat());

126

verify(service).setAge(anyByte());

127

```

128

129

## Collection Matchers

130

131

```java { .api }

132

public static <T> Collection<T> anyCollection();

133

public static <T> Collection<T> anyCollectionOf(Class<T> clazz);

134

public static <T> List<T> anyList();

135

public static <T> List<T> anyListOf(Class<T> clazz);

136

public static <T> Set<T> anySet();

137

public static <T> Set<T> anySetOf(Class<T> clazz);

138

public static <K, V> Map<K, V> anyMap();

139

public static <K, V> Map<K, V> anyMapOf(Class<K> keyClazz, Class<V> valueClazz);

140

```

141

142

**Usage Examples:**

143

144

```java

145

// Generic collection matchers

146

when(service.process(anyList())).thenReturn("processed");

147

when(service.save(anyCollection())).thenReturn(true);

148

149

// Type-specific collection matchers

150

when(service.processUsers(anyListOf(User.class))).thenReturn(results);

151

when(service.processSettings(anyMapOf(String.class, Object.class))).thenReturn(config);

152

153

// Verification

154

verify(service).updateUsers(anySetOf(User.class));

155

verify(cache).putAll(anyMap());

156

```

157

158

## Advanced Matchers

159

160

### Additional Matchers

161

162

```java { .api }

163

public class AdditionalMatchers {

164

public static <T> T not(T value);

165

public static <T> T or(T left, T right);

166

public static <T> T and(T left, T right);

167

public static <T extends Comparable<T>> T geq(T value);

168

public static <T extends Comparable<T>> T leq(T value);

169

public static <T extends Comparable<T>> T gt(T value);

170

public static <T extends Comparable<T>> T lt(T value);

171

public static <T extends Comparable<T>> T cmpEq(T value);

172

public static <T> T[] aryEq(T[] array);

173

public static String find(String regex);

174

}

175

```

176

177

**Usage Examples:**

178

179

```java

180

// Logical matchers

181

when(service.process(not(eq("invalid")))).thenReturn("valid");

182

when(service.handle(or(eq("a"), eq("b")))).thenReturn(true);

183

when(service.validate(and(startsWith("user"), endsWith("@domain.com")))).thenReturn(true);

184

185

// Comparison matchers

186

when(service.processAge(gt(18))).thenReturn("adult");

187

when(service.processScore(geq(90))).thenReturn("excellent");

188

when(service.processQuantity(lt(100))).thenReturn("available");

189

190

// Array equality

191

String[] expectedArray = {"a", "b", "c"};

192

verify(service).processArray(aryEq(expectedArray));

193

194

// Regex find in string

195

verify(logger).log(find("ERROR.*database"));

196

```

197

198

## Custom Matchers

199

200

### Hamcrest Integration

201

202

```java { .api }

203

public static <T> T argThat(Matcher<T> matcher);

204

public static boolean booleanThat(Matcher<Boolean> matcher);

205

public static byte byteThat(Matcher<Byte> matcher);

206

public static char charThat(Matcher<Character> matcher);

207

public static double doubleThat(Matcher<Double> matcher);

208

public static float floatThat(Matcher<Float> matcher);

209

public static int intThat(Matcher<Integer> matcher);

210

public static long longThat(Matcher<Long> matcher);

211

public static short shortThat(Matcher<Short> matcher);

212

```

213

214

**Usage Examples:**

215

216

```java

217

// Hamcrest matchers

218

when(service.process(argThat(hasProperty("name", equalTo("John"))))).thenReturn(user);

219

when(service.calculate(intThat(greaterThan(0)))).thenReturn(result);

220

221

// Custom Hamcrest matcher

222

verify(service).save(argThat(allOf(

223

hasProperty("name", notNullValue()),

224

hasProperty("age", greaterThan(0))

225

)));

226

```

227

228

### Lambda Matchers (Java 8+)

229

230

```java

231

// Custom logic with lambda

232

when(service.process(argThat(user -> user.getAge() > 18))).thenReturn("adult");

233

234

// Complex validation

235

verify(service).save(argThat(user ->

236

user.getName() != null &&

237

user.getEmail().contains("@") &&

238

user.getAge() >= 18

239

));

240

```

241

242

### Custom ArgumentMatcher

243

244

```java { .api }

245

public interface ArgumentMatcher<T> {

246

boolean matches(T argument);

247

}

248

```

249

250

**Usage Example:**

251

252

```java

253

class IsValidEmail implements ArgumentMatcher<String> {

254

public boolean matches(String email) {

255

return email != null && email.contains("@") && email.contains(".");

256

}

257

}

258

259

// Usage

260

when(service.sendEmail(argThat(new IsValidEmail()))).thenReturn(true);

261

```

262

263

## Matcher Best Practices

264

265

### Mixing Matchers and Exact Values

266

267

**Important Rule:** If you use any matcher for one argument, you must use matchers for all arguments:

268

269

```java

270

// WRONG - mixing matchers with exact values

271

verify(mock).someMethod(anyInt(), "exact string");

272

273

// CORRECT - use matchers for all arguments

274

verify(mock).someMethod(anyInt(), eq("exact string"));

275

```

276

277

### Appropriate Matcher Selection

278

279

```java

280

// Good - specific when it matters

281

verify(service).processUser(eq("john123"));

282

283

// Good - flexible when appropriate

284

verify(service).log(anyString());

285

286

// Avoid - too specific when flexibility is better

287

verify(service).log(eq("Processing user john123 at 2023-10-01 10:30:15"));

288

289

// Better - focus on important parts

290

verify(service).log(contains("Processing user john123"));

291

```

292

293

### Performance Considerations

294

295

```java

296

// Good - simple matchers are faster

297

verify(service).process(anyString());

298

299

// Consider performance for complex matchers

300

verify(service).process(argThat(data -> {

301

// Complex computation here

302

return expensiveValidation(data);

303

}));

304

```

305

306

### Readable Test Code

307

308

```java

309

// Good - clear intent

310

verify(emailService).sendEmail(

311

eq("user@example.com"),

312

contains("Welcome"),

313

any(EmailOptions.class)

314

);

315

316

// Avoid - unclear matchers

317

verify(service).process(argThat(x -> x.toString().length() > 5));

318

319

// Better - descriptive matcher

320

verify(service).process(argThat(hasMinimumLength(5)));

321

```

322

323

## Common Matcher Errors

324

325

### InvalidUseOfMatchersException

326

327

```java

328

// WRONG - mixing matchers and values

329

verify(mock).method(anyString(), "value");

330

331

// CORRECT

332

verify(mock).method(anyString(), eq("value"));

333

```

334

335

### Null Pointer with Matchers

336

337

```java

338

// Potentially problematic

339

String nullString = null;

340

when(service.process(eq(nullString))).thenReturn("result");

341

342

// Better

343

when(service.process(isNull())).thenReturn("result");

344

```

345

346

### Overuse of any()

347

348

```java

349

// Avoid - loses test value

350

verify(service).process(any(), any(), any());

351

352

// Better - be specific where it matters

353

verify(service).process(eq("important"), any(), anyInt());

354

```