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

annotations.mddocs/

0

# Annotation-Based Testing

1

2

Mockito provides annotations to streamline test setup by automatically creating mocks, spies, and argument captors. This reduces boilerplate code and makes tests more readable.

3

4

## Core Annotations

5

6

### @Mock Annotation

7

8

Mark fields as mocks for automatic creation:

9

10

```java { .api }

11

@Target(FIELD)

12

@Retention(RUNTIME)

13

@Documented

14

public @interface Mock {

15

Answers answer() default Answers.RETURNS_DEFAULTS;

16

String name() default "";

17

Class<?>[] extraInterfaces() default {};

18

boolean serializable() default false;

19

}

20

```

21

22

**Usage Examples:**

23

24

```java

25

public class UserServiceTest {

26

@Mock

27

private UserRepository userRepository;

28

29

@Mock(name = "emailService")

30

private EmailService emailService;

31

32

@Mock(answer = Answers.RETURNS_SMART_NULLS)

33

private ConfigService configService;

34

35

@Mock(extraInterfaces = {Serializable.class, Cloneable.class})

36

private DataProcessor processor;

37

38

@Mock(serializable = true)

39

private CacheService cacheService;

40

41

@Before

42

public void setUp() {

43

MockitoAnnotations.initMocks(this);

44

}

45

}

46

```

47

48

### @Spy Annotation

49

50

Mark fields as spies for wrapping real objects:

51

52

```java { .api }

53

@Retention(RUNTIME)

54

@Target(FIELD)

55

@Documented

56

public @interface Spy { }

57

```

58

59

**Usage Examples:**

60

61

```java

62

public class ServiceTest {

63

// Spy with explicit instance

64

@Spy

65

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

66

67

// Spy with default constructor (Mockito creates instance)

68

@Spy

69

private UserService userService;

70

71

@Before

72

public void setUp() {

73

MockitoAnnotations.initMocks(this);

74

}

75

76

@Test

77

public void testSpyBehavior() {

78

// Real method is called

79

spyList.add("item");

80

assertEquals(1, spyList.size());

81

82

// Can stub methods

83

doReturn(100).when(spyList).size();

84

assertEquals(100, spyList.size());

85

}

86

}

87

```

88

89

### @InjectMocks Annotation

90

91

Mark fields where mocks should be injected:

92

93

```java { .api }

94

@Documented

95

@Target(FIELD)

96

@Retention(RUNTIME)

97

public @interface InjectMocks { }

98

```

99

100

**Usage Examples:**

101

102

```java

103

public class UserServiceTest {

104

@Mock

105

private UserRepository repository;

106

107

@Mock

108

private EmailService emailService;

109

110

@Mock

111

private ValidationService validationService;

112

113

@InjectMocks

114

private UserService userService; // Mocks will be injected here

115

116

@Before

117

public void setUp() {

118

MockitoAnnotations.initMocks(this);

119

}

120

121

@Test

122

public void testUserCreation() {

123

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

124

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

125

126

User result = userService.createUser("John", "john@example.com");

127

128

assertEquals("John", result.getName());

129

verify(emailService).sendWelcomeEmail(user);

130

}

131

}

132

```

133

134

### @Captor Annotation

135

136

Mark fields as argument captors:

137

138

```java { .api }

139

@Retention(RUNTIME)

140

@Target(FIELD)

141

@Documented

142

public @interface Captor { }

143

```

144

145

**Usage Examples:**

146

147

```java

148

public class EmailServiceTest {

149

@Mock

150

private EmailProvider emailProvider;

151

152

@Captor

153

private ArgumentCaptor<EmailMessage> messageCaptor;

154

155

@Captor

156

private ArgumentCaptor<String> stringCaptor;

157

158

@InjectMocks

159

private EmailService emailService;

160

161

@Before

162

public void setUp() {

163

MockitoAnnotations.initMocks(this);

164

}

165

166

@Test

167

public void testEmailSending() {

168

emailService.sendWelcomeEmail("user@example.com", "John");

169

170

verify(emailProvider).send(messageCaptor.capture());

171

EmailMessage capturedMessage = messageCaptor.getValue();

172

173

assertEquals("user@example.com", capturedMessage.getTo());

174

assertEquals("Welcome John!", capturedMessage.getSubject());

175

}

176

}

177

```

178

179

## Initialization

180

181

### MockitoAnnotations.initMocks()

182

183

Initialize all annotated fields:

184

185

```java { .api }

186

public class MockitoAnnotations {

187

public static void initMocks(Object testClass);

188

}

189

```

190

191

**Usage Patterns:**

192

193

```java

194

// In @Before method

195

@Before

196

public void setUp() {

197

MockitoAnnotations.initMocks(this);

198

}

199

200

// In test constructor

201

public MyTest() {

202

MockitoAnnotations.initMocks(this);

203

}

204

205

// In @BeforeEach (JUnit 5)

206

@BeforeEach

207

void setUp() {

208

MockitoAnnotations.initMocks(this);

209

}

210

```

211

212

## Dependency Injection Strategies

213

214

### Constructor Injection

215

216

Mockito tries constructor injection first (biggest constructor):

217

218

```java

219

public class UserService {

220

private final UserRepository repository;

221

private final EmailService emailService;

222

223

// Mockito will use this constructor

224

public UserService(UserRepository repository, EmailService emailService) {

225

this.repository = repository;

226

this.emailService = emailService;

227

}

228

}

229

230

public class UserServiceTest {

231

@Mock private UserRepository repository;

232

@Mock private EmailService emailService;

233

@InjectMocks private UserService userService;

234

235

// Mocks will be injected via constructor

236

}

237

```

238

239

### Setter Injection

240

241

If constructor injection fails, Mockito tries setter injection:

242

243

```java

244

public class UserService {

245

private UserRepository repository;

246

private EmailService emailService;

247

248

public void setRepository(UserRepository repository) {

249

this.repository = repository;

250

}

251

252

public void setEmailService(EmailService emailService) {

253

this.emailService = emailService;

254

}

255

}

256

```

257

258

### Field Injection

259

260

If setter injection fails, Mockito tries field injection:

261

262

```java

263

public class UserService {

264

private UserRepository repository; // Will be injected

265

private EmailService emailService; // Will be injected

266

}

267

```

268

269

## JUnit Integration

270

271

### MockitoJUnitRunner

272

273

Automatically initializes mocks without explicit setup:

274

275

```java { .api }

276

public class MockitoJUnitRunner extends Runner { }

277

```

278

279

**Usage:**

280

281

```java

282

@RunWith(MockitoJUnitRunner.class)

283

public class UserServiceTest {

284

@Mock

285

private UserRepository repository;

286

287

@InjectMocks

288

private UserService userService;

289

290

// No need for MockitoAnnotations.initMocks()

291

292

@Test

293

public void testUser() {

294

// Test implementation

295

}

296

}

297

```

298

299

### Verbose Runner

300

301

Enhanced debugging with verbose output:

302

303

```java { .api }

304

public class VerboseMockitoJUnitRunner extends MockitoJUnitRunner { }

305

```

306

307

**Usage:**

308

309

```java

310

@RunWith(VerboseMockitoJUnitRunner.class)

311

public class UserServiceTest {

312

// Provides detailed output for debugging

313

}

314

```

315

316

### MockitoRule (Alternative to Runner)

317

318

Use when you can't use MockitoJUnitRunner:

319

320

```java { .api }

321

public interface MockitoRule extends TestRule { }

322

323

public class MockitoJUnit {

324

public static MockitoRule rule();

325

}

326

```

327

328

**Usage:**

329

330

```java

331

public class UserServiceTest {

332

@Rule

333

public MockitoRule mockitoRule = MockitoJUnit.rule();

334

335

@Mock

336

private UserRepository repository;

337

338

@InjectMocks

339

private UserService userService;

340

}

341

```

342

343

## Best Practices

344

345

### Field vs Method Initialization

346

347

```java

348

// Good - field initialization for simple cases

349

@Spy

350

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

351

352

// Good - method initialization for complex setup

353

@Spy

354

private ComplexService service;

355

356

@Before

357

public void setUp() {

358

service = new ComplexService(config, dependencies);

359

MockitoAnnotations.initMocks(this);

360

}

361

```

362

363

### Naming Conventions

364

365

```java

366

// Good - descriptive names

367

@Mock(name = "userRepository")

368

private UserRepository userRepository;

369

370

@Mock(name = "emailService")

371

private EmailService emailService;

372

373

// Good - match field names with dependencies

374

public class UserService {

375

private UserRepository userRepository; // Matches mock field name

376

private EmailService emailService; // Matches mock field name

377

}

378

```

379

380

### Mock Configuration

381

382

```java

383

// Good - appropriate answers for test scenarios

384

@Mock(answer = Answers.RETURNS_SMART_NULLS)

385

private ComplexService complexService;

386

387

@Mock(answer = Answers.RETURNS_DEEP_STUBS)

388

private FluentApi fluentApi;

389

390

// Good - extra interfaces when needed

391

@Mock(extraInterfaces = {Serializable.class})

392

private DataTransferObject dto;

393

```

394

395

### Injection Best Practices

396

397

```java

398

public class ServiceTest {

399

@Mock private Dependency1 dep1;

400

@Mock private Dependency2 dep2;

401

402

@InjectMocks private Service service;

403

404

@Test

405

public void testServiceBehavior() {

406

// Configure mocks

407

when(dep1.getData()).thenReturn("data");

408

409

// Test service that uses injected mocks

410

String result = service.processData();

411

412

// Verify interactions

413

verify(dep1).getData();

414

assertEquals("processed: data", result);

415

}

416

}

417

```

418

419

## Common Pitfalls

420

421

### Initialization Order

422

423

```java

424

// WRONG - calling initMocks() in constructor of superclass

425

public class BaseTest {

426

public BaseTest() {

427

MockitoAnnotations.initMocks(this); // Subclass fields not yet initialized

428

}

429

}

430

431

// CORRECT - use @Before or test runner

432

@RunWith(MockitoJUnitRunner.class)

433

public class MyTest extends BaseTest {

434

@Mock private Service service;

435

}

436

```

437

438

### Spy Limitations

439

440

```java

441

// Mockito cannot instantiate these:

442

@Spy private InnerClass inner; // Inner classes

443

@Spy private AbstractClass abs; // Abstract classes

444

@Spy private Interface intf; // Interfaces

445

@Spy private final FinalClass fin; // Final fields

446

@Spy private static StaticClass stat; // Static fields

447

```

448

449

### Injection Failures

450

451

```java

452

// Will fail injection - no matching constructor/setter/field

453

public class Service {

454

public Service(String config, int port) { } // No default constructor

455

// No setters or matching fields

456

}

457

458

public class Test {

459

@Mock private UserRepository repo; // Type doesn't match constructor params

460

@InjectMocks private Service service; // Injection will fail silently

461

}

462

```