or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

additional-answers.mdadditional-matchers.mdadvanced-features.mdannotations.mdargument-matching.mdbdd-testing.mdindex.mdmock-creation.mdstatic-mocking.mdstubbing.mdverification.md

additional-answers.mddocs/

0

# Additional Answer Behaviors

1

2

This section covers advanced stubbing behaviors that go beyond basic return values and exception throwing, providing sophisticated answer strategies for complex testing scenarios.

3

4

## Argument-Based Return Values

5

6

### Return First Argument

7

8

Return the first parameter of an invocation as the method's return value.

9

10

```java { .api }

11

public static <T> Answer<T> returnsFirstArg()

12

```

13

14

**Usage Examples:**

15

16

```java

17

CarKeyFob mockKeyFob = mock(CarKeyFob.class);

18

PersonService mockPerson = mock(PersonService.class);

19

20

// Return the first argument passed to the method

21

when(mockKeyFob.authenticate(any(CarKey.class))).will(returnsFirstArg());

22

when(mockPerson.remember(any(Dream.class), any(Dream[].class))).will(returnsFirstArg());

23

24

// Use the mock

25

CarKey key = new CarKey("ABC123");

26

CarKey result = mockKeyFob.authenticate(key); // Returns the same CarKey instance

27

28

Dream dream1 = new Dream("flying");

29

Dream result2 = mockPerson.remember(dream1, new Dream("falling")); // Returns dream1

30

31

// Works with varargs - returns first individual argument

32

Dream[] dreams = {new Dream("running"), new Dream("swimming")};

33

Dream result3 = mockPerson.remember(dreams[0], dreams[1]); // Returns dreams[0]

34

```

35

36

### Return Second Argument

37

38

Return the second parameter of an invocation as the method's return value.

39

40

```java { .api }

41

public static <T> Answer<T> returnsSecondArg()

42

```

43

44

**Usage Examples:**

45

46

```java

47

TraderService mockTrader = mock(TraderService.class);

48

PersonService mockPerson = mock(PersonService.class);

49

50

// Return the second argument passed to the method

51

when(mockTrader.apply(any(Formula.class), any(Swap.class))).will(returnsSecondArg());

52

when(mockPerson.remember(any(Dream.class), any(Dream[].class))).will(returnsSecondArg());

53

54

// Use the mock

55

Formula formula = new Formula("Lee's Formula");

56

Swap swap = new CreditDefaultSwap();

57

Swap result = mockTrader.apply(formula, swap); // Returns the swap instance

58

59

Dream dream1 = new Dream("flying");

60

Dream dream2 = new Dream("falling");

61

Dream[] otherDreams = mockPerson.remember(dream1, dream2, new Dream("running"));

62

// Returns otherDreams array when second parameter is varargs

63

```

64

65

### Return Last Argument

66

67

Return the last parameter of an invocation as the method's return value.

68

69

```java { .api }

70

public static <T> Answer<T> returnsLastArg()

71

```

72

73

**Usage Examples:**

74

75

```java

76

PersonService mockPerson = mock(PersonService.class);

77

78

// Return the last argument passed to the method

79

when(mockPerson.remember(any(Dream.class), any(), any(), any())).will(returnsLastArg());

80

81

// Use the mock

82

Dream dream1 = new Dream("flying");

83

Dream dream2 = new Dream("falling");

84

Dream dream3 = new Dream("running");

85

Dream dream4 = new Dream("swimming");

86

87

Dream result = mockPerson.remember(dream1, dream2, dream3, dream4); // Returns dream4

88

89

// Works with varargs - returns last element or varargs array

90

Dream[] varargDreams = {new Dream("dancing")};

91

Dream[] result2 = mockPerson.rememberArray(dream1, dream2, dream3, varargDreams);

92

// Returns varargDreams array if return type matches varargs type

93

```

94

95

### Return Argument at Position

96

97

Return the parameter at a specific position in the invocation.

98

99

```java { .api }

100

public static <T> Answer<T> returnsArgAt(int position)

101

```

102

103

**Usage Examples:**

104

105

```java

106

PersonService mockPerson = mock(PersonService.class);

107

108

// Return argument at index 2 (zero-based)

109

when(mockPerson.remember(any(), any(), any(), any())).will(returnsArgAt(2));

110

111

// Use the mock

112

Dream dream1 = new Dream("flying");

113

Dream dream2 = new Dream("falling");

114

Dream dream3 = new Dream("running");

115

Dream dream4 = new Dream("swimming");

116

117

Dream result = mockPerson.remember(dream1, dream2, dream3, dream4); // Returns dream3

118

119

// Works with varargs expansion

120

when(mockPerson.remember(any(Dream.class), any(Dream[].class))).will(returnsArgAt(2));

121

Dream expandedResult = mockPerson.remember(dream1, dream2, dream3, dream4);

122

// Returns dream3 (varargs expanded to individual arguments)

123

```

124

125

## Call Delegation

126

127

### Delegate to Real Object

128

129

Forward all method calls to a delegate object, useful for partial mocks and final classes.

130

131

```java { .api }

132

public static <T> Answer<T> delegatesTo(Object delegate)

133

```

134

135

**Usage Examples:**

136

137

```java

138

// Final class that can't be spied normally

139

final class DontYouDareToMockMe implements List<String> {

140

private List<String> list = new ArrayList<>();

141

142

@Override

143

public boolean add(String item) {

144

return list.add(item);

145

}

146

147

@Override

148

public String get(int index) {

149

return list.get(index);

150

}

151

// ... other List methods

152

}

153

154

DontYouDareToMockMe awesomeList = new DontYouDareToMockMe();

155

awesomeList.add("delegated-item");

156

157

// Create mock that delegates to the real object

158

List<String> mockList = mock(List.class, delegatesTo(awesomeList));

159

160

// Method calls are forwarded to awesomeList

161

String result = mockList.get(0); // Returns "delegated-item"

162

163

// Important: Use doReturn for stubbing to avoid calling real method

164

doReturn("stubbed-value").when(mockList).get(0);

165

166

// Delegate can be different type with compatible method signatures

167

UserRepository realRepo = new DatabaseUserRepository();

168

UserRepository mockRepo = mock(UserRepository.class, delegatesTo(realRepo));

169

// Calls will be forwarded to realRepo

170

```

171

172

## Collection-Based Returns

173

174

### Return Elements from Collection

175

176

Return elements from a collection sequentially, repeating the last element forever.

177

178

```java { .api }

179

public static <T> Answer<T> returnsElementsOf(Collection<?> elements)

180

```

181

182

**Usage Examples:**

183

184

```java

185

NumberService mockService = mock(NumberService.class);

186

187

// Return elements in sequence

188

List<Integer> numbers = Arrays.asList(1, 2, 3);

189

when(mockService.getNextNumber()).thenAnswer(returnsElementsOf(numbers));

190

191

// Use the mock

192

int first = mockService.getNextNumber(); // Returns 1

193

int second = mockService.getNextNumber(); // Returns 2

194

int third = mockService.getNextNumber(); // Returns 3

195

int fourth = mockService.getNextNumber(); // Returns 3 (last element repeats)

196

int fifth = mockService.getNextNumber(); // Returns 3 (continues repeating)

197

198

// Equivalent to traditional stubbing

199

// when(mockService.getNextNumber()).thenReturn(1, 2, 3);

200

201

// Works with any collection type

202

Set<String> statuses = new LinkedHashSet<>(Arrays.asList("pending", "processing", "completed"));

203

when(mockService.getStatus()).thenAnswer(returnsElementsOf(statuses));

204

```

205

206

## Delayed Answers

207

208

### Answer with Delay

209

210

Return an answer after a specified delay in milliseconds.

211

212

```java { .api }

213

public static <T> Answer<T> answersWithDelay(long sleepyTime, Answer<T> answer)

214

```

215

216

**Usage Examples:**

217

218

```java

219

NetworkService mockService = mock(NetworkService.class);

220

221

// Simulate network latency

222

Answer<String> delayedResponse = answersWithDelay(1000, invocation -> "response");

223

when(mockService.fetchData()).thenAnswer(delayedResponse);

224

225

// Use with other answers

226

Answer<String> delayedArgReturn = answersWithDelay(500, returnsFirstArg());

227

when(mockService.echo(anyString())).thenAnswer(delayedArgReturn);

228

229

// Combine with exception throwing

230

Answer<String> delayedFailure = answersWithDelay(200,

231

invocation -> { throw new TimeoutException("Simulated timeout"); });

232

when(mockService.unreliableCall()).thenAnswer(delayedFailure);

233

234

// Use the mock

235

long start = System.currentTimeMillis();

236

String result = mockService.fetchData(); // Takes ~1000ms to return

237

long elapsed = System.currentTimeMillis() - start; // ~1000ms

238

```

239

240

## Functional Interface Answers

241

242

### Typed Return Answers (1-6 Parameters)

243

244

Create strongly-typed answers using functional interfaces for methods that return values.

245

246

```java { .api }

247

public static <T, A> Answer<T> answer(Answer1<T, A> answer)

248

public static <T, A, B> Answer<T> answer(Answer2<T, A, B> answer)

249

public static <T, A, B, C> Answer<T> answer(Answer3<T, A, B, C> answer)

250

public static <T, A, B, C, D> Answer<T> answer(Answer4<T, A, B, C, D> answer)

251

public static <T, A, B, C, D, E> Answer<T> answer(Answer5<T, A, B, C, D, E> answer)

252

public static <T, A, B, C, D, E, F> Answer<T> answer(Answer6<T, A, B, C, D, E, F> answer)

253

```

254

255

**Usage Examples:**

256

257

```java

258

UserService mockService = mock(UserService.class);

259

260

// Single parameter answer with type safety

261

Answer1<User, String> userByName = name -> new User(name.toLowerCase());

262

when(mockService.findUser(anyString())).thenAnswer(answer(userByName));

263

264

// Two parameter answer

265

Answer2<String, String, Integer> formatter = (name, age) -> name + " (" + age + ")";

266

when(mockService.formatUser(anyString(), anyInt())).thenAnswer(answer(formatter));

267

268

// Three parameter answer with complex logic

269

Answer3<Double, Double, Double, String> calculator = (x, y, operation) -> {

270

switch (operation) {

271

case "add": return x + y;

272

case "multiply": return x * y;

273

default: return 0.0;

274

}

275

};

276

when(mockService.calculate(anyDouble(), anyDouble(), anyString()))

277

.thenAnswer(answer(calculator));

278

279

// Using method references

280

Answer1<String, String> upperCaser = String::toUpperCase;

281

when(mockService.transform(anyString())).thenAnswer(answer(upperCaser));

282

283

// Lambda expressions for simple cases

284

when(mockService.processNumber(anyInt()))

285

.thenAnswer(answer((Integer n) -> n * 2));

286

```

287

288

### Typed Void Answers (1-6 Parameters)

289

290

Create strongly-typed answers using functional interfaces for void methods.

291

292

```java { .api }

293

public static <A> Answer<Void> answerVoid(VoidAnswer1<A> answer)

294

public static <A, B> Answer<Void> answerVoid(VoidAnswer2<A, B> answer)

295

public static <A, B, C> Answer<Void> answerVoid(VoidAnswer3<A, B, C> answer)

296

public static <A, B, C, D> Answer<Void> answerVoid(VoidAnswer4<A, B, C, D> answer)

297

public static <A, B, C, D, E> Answer<Void> answerVoid(VoidAnswer5<A, B, C, D, E> answer)

298

public static <A, B, C, D, E, F> Answer<Void> answerVoid(VoidAnswer6<A, B, C, D, E, F> answer)

299

```

300

301

**Usage Examples:**

302

303

```java

304

LoggingService mockService = mock(LoggingService.class);

305

306

// Single parameter void answer

307

VoidAnswer1<String> logger = message -> System.out.println("LOG: " + message);

308

doAnswer(answerVoid(logger)).when(mockService).log(anyString());

309

310

// Two parameter void answer

311

VoidAnswer2<String, LogLevel> levelLogger = (message, level) ->

312

System.out.println("[" + level + "] " + message);

313

doAnswer(answerVoid(levelLogger)).when(mockService).log(anyString(), any(LogLevel.class));

314

315

// Complex void behavior with side effects

316

List<String> auditLog = new ArrayList<>();

317

VoidAnswer3<String, String, Date> auditor = (user, action, timestamp) -> {

318

auditLog.add(user + " performed " + action + " at " + timestamp);

319

};

320

doAnswer(answerVoid(auditor)).when(mockService).audit(anyString(), anyString(), any(Date.class));

321

322

// Method reference for existing methods

323

VoidAnswer1<String> printer = System.out::println;

324

doAnswer(answerVoid(printer)).when(mockService).output(anyString());

325

326

// Lambda for state modification

327

AtomicInteger counter = new AtomicInteger(0);

328

doAnswer(answerVoid((String msg) -> counter.incrementAndGet()))

329

.when(mockService).log(anyString());

330

```

331

332

## Complex Answer Combinations

333

334

### Combining Multiple Answer Strategies

335

336

Create sophisticated mock behaviors by combining different answer types.

337

338

**Usage Examples:**

339

340

```java

341

PaymentService mockService = mock(PaymentService.class);

342

343

// Combine delegation with delay for realistic simulation

344

PaymentProcessor realProcessor = new DefaultPaymentProcessor();

345

Answer<PaymentResult> realisticAnswer = answersWithDelay(500, delegatesTo(realProcessor));

346

when(mockService.processPayment(any())).thenAnswer(realisticAnswer);

347

348

// Sequential behavior with different answer types

349

when(mockService.getTransactionId())

350

.thenAnswer(returnsElementsOf(Arrays.asList("TX001", "TX002", "TX003")))

351

.thenAnswer(answer((InvocationOnMock inv) -> "TX" + System.currentTimeMillis()));

352

353

// Argument-dependent answers with functional interfaces

354

Answer2<String, String, Double> feeCalculator = (type, currency) -> {

355

if ("premium".equals(type)) return 0.01;

356

if ("USD".equals(currency)) return 0.025;

357

return 0.03;

358

};

359

360

when(mockService.calculateFee(anyString(), anyString()))

361

.thenAnswer(answer(feeCalculator));

362

363

// Error simulation with delays

364

Answer<Void> unreliableService = answersWithDelay(1000,

365

answerVoid((String request) -> {

366

if (request.contains("error")) {

367

throw new ServiceException("Simulated failure");

368

}

369

}));

370

doAnswer(unreliableService).when(mockService).processRequest(anyString());

371

```

372

373

## Import Statements

374

375

To use AdditionalAnswers, include these imports in your test files:

376

377

```java

378

import static org.mockito.AdditionalAnswers.*;

379

import org.mockito.stubbing.Answer1;

380

import org.mockito.stubbing.Answer2;

381

import org.mockito.stubbing.VoidAnswer1;

382

import org.mockito.stubbing.VoidAnswer2;

383

// Import additional Answer3-Answer6 and VoidAnswer3-VoidAnswer6 as needed

384

```

385

386

This provides access to all additional answer methods including `returnsFirstArg`, `returnsSecondArg`, `returnsLastArg`, `returnsArgAt`, `delegatesTo`, `returnsElementsOf`, `answersWithDelay`, and the type-safe `answer`/`answerVoid` methods.

387

388

## Best Practices

389

390

### When to Use Additional Answers

391

392

- **Argument Echoing**: Use `returnsFirstArg`, `returnsSecondArg`, `returnsLastArg`, `returnsArgAt` when the return value should be one of the input parameters

393

- **Partial Mocking**: Use `delegatesTo` for final classes, proxied objects, or when you need most real behavior with selective stubbing

394

- **Sequential Data**: Use `returnsElementsOf` when simulating iterative processes or data streams

395

- **Performance Testing**: Use `answersWithDelay` to simulate network latency, database delays, or slow operations

396

- **Type Safety**: Use `answer`/`answerVoid` with functional interfaces for compile-time type checking and cleaner lambda expressions

397

398

### Performance Considerations

399

400

- `delegatesTo` calls real methods, which may have performance implications or side effects

401

- `answersWithDelay` introduces actual delays in test execution - use judiciously

402

- Functional interface answers have minimal overhead compared to traditional Answer implementations

403

404

### Testing Guidelines

405

406

```java

407

// Good: Clear intent with appropriate answer type

408

when(mockCache.get(anyString())).will(returnsFirstArg()); // Cache returns what you put in

409

410

// Good: Type-safe functional answers

411

Answer1<User, Long> userLoader = id -> userRepository.findById(id);

412

when(mockService.loadUser(anyLong())).thenAnswer(answer(userLoader));

413

414

// Good: Realistic simulation

415

when(mockNetworkService.fetchData())

416

.thenAnswer(answersWithDelay(100, returnsElementsOf(testData)));

417

418

// Avoid: Using delegation when simple stubbing suffices

419

// when(mockList.size()).thenAnswer(delegatesTo(realList)); // Overkill

420

when(mockList.size()).thenReturn(5); // Better

421

```

422

423

### Debugging Tips

424

425

When using complex answers, consider logging or debugging support:

426

427

```java

428

// Add logging to functional answers for debugging

429

Answer1<String, String> debuggingProcessor = input -> {

430

String result = processInput(input);

431

System.out.println("Processed '" + input + "' -> '" + result + "'");

432

return result;

433

};

434

when(mockService.process(anyString())).thenAnswer(answer(debuggingProcessor));

435

```