or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-overrides.mdcore-test-support.mddao-testing.mdindex.mdjunit5-extensions.mdresource-testing.md

junit5-extensions.mddocs/

0

# JUnit 5 Extensions

1

2

Modern JUnit 5 integration providing declarative test setup through annotations and extensions. Supports full application testing, resource testing, DAO testing, and lightweight client testing with automatic lifecycle management.

3

4

## Capabilities

5

6

### DropwizardAppExtension

7

8

JUnit 5 extension for complete Dropwizard application testing with automatic lifecycle management, HTTP client setup, and access to all application components.

9

10

```java { .api }

11

/**

12

* JUnit 5 extension for full Dropwizard application testing

13

* @param <C> Configuration type extending Configuration

14

*/

15

public class DropwizardAppExtension<C extends Configuration>

16

implements DropwizardExtension, BeforeAllCallback, AfterAllCallback {

17

18

// Constructor variants matching DropwizardTestSupport

19

/**

20

* Create extension with application class and configuration file

21

* @param applicationClass Dropwizard application class

22

* @param configPath Path to configuration file

23

* @param configOverrides Configuration overrides for testing

24

*/

25

public DropwizardAppExtension(Class<? extends Application<C>> applicationClass,

26

String configPath,

27

ConfigOverride... configOverrides);

28

29

/**

30

* Create extension with application class and configuration object

31

* @param applicationClass Dropwizard application class

32

* @param configuration Pre-built configuration instance

33

* @param configOverrides Configuration overrides for testing

34

*/

35

public DropwizardAppExtension(Class<? extends Application<C>> applicationClass,

36

C configuration,

37

ConfigOverride... configOverrides);

38

39

// Application access methods

40

/**

41

* Get the application configuration instance

42

* @return Configuration object used by the application

43

*/

44

public C getConfiguration();

45

46

/**

47

* Get the running Dropwizard application instance

48

* @return Application instance with full type information

49

*/

50

public <A extends Application<C>> A getApplication();

51

52

/**

53

* Get the Dropwizard runtime environment

54

* @return Environment instance with access to metrics, validation, etc.

55

*/

56

public Environment getEnvironment();

57

58

/**

59

* Get the Jackson ObjectMapper used by the application

60

* @return ObjectMapper for JSON/YAML processing

61

*/

62

public ObjectMapper getObjectMapper();

63

64

// Network access methods

65

/**

66

* Get the main application HTTP port

67

* @return Port number for application endpoints

68

*/

69

public int getLocalPort();

70

71

/**

72

* Get the admin interface HTTP port

73

* @return Port number for admin endpoints

74

*/

75

public int getAdminPort();

76

77

/**

78

* Get the port for a specific connector by index

79

* @param connectorIndex Zero-based connector index

80

* @return Port number for the specified connector

81

*/

82

public int getPort(int connectorIndex);

83

84

// HTTP testing support

85

/**

86

* Get a configured HTTP client for testing application endpoints

87

* Uses default timeouts and response buffering for reliable testing

88

* @return JAX-RS Client configured for testing

89

*/

90

public Client client();

91

92

/**

93

* Get the underlying DropwizardTestSupport instance

94

* @return DropwizardTestSupport managing the application lifecycle

95

*/

96

public DropwizardTestSupport<C> getTestSupport();

97

98

// Configuration and extension methods

99

/**

100

* Add a lifecycle listener for application events

101

* @param listener ServiceListener instance for handling events

102

* @return This DropwizardAppExtension instance for chaining

103

*/

104

public DropwizardAppExtension<C> addListener(ServiceListener<C> listener);

105

106

/**

107

* Add a managed object to the application lifecycle

108

* @param managed Managed object to start/stop with application

109

* @return This DropwizardAppExtension instance for chaining

110

*/

111

public DropwizardAppExtension<C> manage(Managed managed);

112

113

/**

114

* Create a customizable Jersey client builder

115

* Override this method to customize HTTP client configuration

116

* @return JerseyClientBuilder for custom client setup

117

*/

118

protected JerseyClientBuilder clientBuilder();

119

}

120

```

121

122

**Usage Examples:**

123

124

```java

125

// Basic application testing

126

@RegisterExtension

127

public static final DropwizardAppExtension<MyConfiguration> APP =

128

new DropwizardAppExtension<>(

129

MyApplication.class,

130

ResourceHelpers.resourceFilePath("test-config.yml")

131

);

132

133

@Test

134

public void testApplicationEndpoint() {

135

String response = APP.client()

136

.target("http://localhost:" + APP.getLocalPort() + "/api/health")

137

.request()

138

.get(String.class);

139

140

assertThat(response).contains("healthy");

141

}

142

143

// With configuration overrides

144

@RegisterExtension

145

public static final DropwizardAppExtension<MyConfiguration> APP =

146

new DropwizardAppExtension<>(

147

MyApplication.class,

148

ResourceHelpers.resourceFilePath("test-config.yml"),

149

ConfigOverride.randomPorts(),

150

ConfigOverride.config("database.url", "jdbc:h2:mem:test")

151

);

152

153

// With pre-built configuration

154

public static MyConfiguration createTestConfiguration() {

155

MyConfiguration config = new MyConfiguration();

156

config.setDatabaseUrl("jdbc:h2:mem:test");

157

config.getServerFactory().setApplicationConnectors(/* custom connectors */);

158

return config;

159

}

160

161

@RegisterExtension

162

public static final DropwizardAppExtension<MyConfiguration> APP =

163

new DropwizardAppExtension<>(MyApplication.class, createTestConfiguration());

164

165

// With lifecycle listeners

166

@RegisterExtension

167

public static final DropwizardAppExtension<MyConfiguration> APP =

168

new DropwizardAppExtension<MyConfiguration>(

169

MyApplication.class,

170

ResourceHelpers.resourceFilePath("test-config.yml")

171

).addListener(new ServiceListener<MyConfiguration>() {

172

@Override

173

public void onRun(MyConfiguration configuration,

174

Environment environment,

175

DropwizardTestSupport<MyConfiguration> rule) {

176

// Initialize test data, mock external services, etc.

177

TestDataLoader.loadTestData(environment.getApplicationContext());

178

}

179

});

180

181

// Testing with custom HTTP client configuration

182

public class CustomAppExtension extends DropwizardAppExtension<MyConfiguration> {

183

public CustomAppExtension() {

184

super(MyApplication.class, ResourceHelpers.resourceFilePath("test-config.yml"));

185

}

186

187

@Override

188

protected JerseyClientBuilder clientBuilder() {

189

return super.clientBuilder()

190

.connectTimeout(Duration.ofSeconds(10))

191

.readTimeout(Duration.ofSeconds(30))

192

.register(new CustomClientFilter());

193

}

194

}

195

196

@RegisterExtension

197

public static final CustomAppExtension APP = new CustomAppExtension();

198

```

199

200

### ResourceExtension

201

202

JUnit 5 extension for isolated JAX-RS resource testing without full application bootstrap, providing fast unit testing of individual REST endpoints.

203

204

```java { .api }

205

/**

206

* JUnit 5 extension for isolated JAX-RS resource testing

207

*/

208

public class ResourceExtension implements DropwizardExtension {

209

210

/**

211

* Create a new ResourceExtension builder for configuration

212

* @return Builder instance for fluent configuration

213

*/

214

public static Builder builder();

215

216

/**

217

* Get a JAX-RS WebTarget for making HTTP requests to resources

218

* @param path Path to append to base URI

219

* @return WebTarget for the specified path

220

*/

221

public WebTarget target(String path);

222

223

/**

224

* Get the underlying JAX-RS Client for advanced HTTP operations

225

* @return JAX-RS Client instance

226

*/

227

public Client client();

228

229

/**

230

* Get the underlying JerseyTest instance for advanced testing

231

* @return JerseyTest instance managing the test environment

232

*/

233

public JerseyTest getJerseyTest();

234

235

/**

236

* Get the Bean Validator used by the resource testing environment

237

* @return Validator instance for bean validation

238

*/

239

public Validator getValidator();

240

241

/**

242

* Get the Jackson ObjectMapper used for JSON serialization/deserialization

243

* @return ObjectMapper instance

244

*/

245

public ObjectMapper getObjectMapper();

246

247

/**

248

* Get the client configurator for custom client setup

249

* @return Consumer for ClientConfig customization

250

*/

251

public Consumer<ClientConfig> getClientConfigurator();

252

}

253

```

254

255

**Usage Examples:**

256

257

```java

258

// Basic resource testing

259

@RegisterExtension

260

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

261

.addResource(new UserResource())

262

.build();

263

264

@Test

265

public void testGetUsers() {

266

List<User> users = RESOURCE.target("/users")

267

.request(MediaType.APPLICATION_JSON)

268

.get(new GenericType<List<User>>() {});

269

270

assertThat(users).isNotEmpty();

271

}

272

273

// With dependency injection

274

UserService userService = mock(UserService.class);

275

276

@RegisterExtension

277

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

278

.addResource(new UserResource(userService))

279

.build();

280

281

@Test

282

public void testCreateUser() {

283

when(userService.create(any(User.class)))

284

.thenReturn(new User(1L, "John", "john@example.com"));

285

286

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

287

288

Response response = RESOURCE.target("/users")

289

.request()

290

.post(Entity.json(newUser));

291

292

assertThat(response.getStatus()).isEqualTo(201);

293

294

User createdUser = response.readEntity(User.class);

295

assertThat(createdUser.getId()).isNotNull();

296

}

297

```

298

299

### DAOTestExtension

300

301

JUnit 5 extension for Hibernate DAO testing with automated database setup, transaction management, and cleanup.

302

303

```java { .api }

304

/**

305

* JUnit 5 extension for Hibernate DAO testing

306

*/

307

public class DAOTestExtension implements DropwizardExtension, BeforeAllCallback, AfterAllCallback {

308

309

/**

310

* Create a new DAOTestExtension builder for configuration

311

* @return Builder instance for fluent database configuration

312

*/

313

public static Builder newBuilder();

314

315

/**

316

* Get the Hibernate SessionFactory for database operations

317

* @return SessionFactory instance for creating sessions

318

*/

319

public SessionFactory getSessionFactory();

320

321

/**

322

* Execute code within a database transaction with return value

323

* @param call Callable to execute within transaction

324

* @return Result of the callable execution

325

* @throws Exception if the callable execution fails

326

*/

327

public <T> T inTransaction(Callable<T> call) throws Exception;

328

329

/**

330

* Execute code within a database transaction without return value

331

* @param action Runnable to execute within transaction

332

* @throws Exception if the action execution fails

333

*/

334

public void inTransaction(Runnable action) throws Exception;

335

}

336

```

337

338

**Usage Examples:**

339

340

```java

341

// Basic DAO testing

342

@RegisterExtension

343

public static final DAOTestExtension DAO_TEST = DAOTestExtension.newBuilder()

344

.addEntityClass(User.class)

345

.addEntityClass(Order.class)

346

.build();

347

348

@Test

349

public void testUserDAO() throws Exception {

350

UserDAO userDAO = new UserDAO(DAO_TEST.getSessionFactory());

351

352

User user = DAO_TEST.inTransaction(() -> {

353

User newUser = new User("Alice", "alice@example.com");

354

return userDAO.save(newUser);

355

});

356

357

assertThat(user.getId()).isNotNull();

358

}

359

360

// With custom database configuration

361

@RegisterExtension

362

public static final DAOTestExtension DAO_TEST = DAOTestExtension.newBuilder()

363

.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")

364

.addEntityClass(User.class)

365

.setShowSql(true)

366

.setHbm2DdlAuto("create-drop")

367

.build();

368

```

369

370

### DropwizardClientExtension

371

372

JUnit 5 extension for lightweight HTTP client testing with minimal Dropwizard setup.

373

374

```java { .api }

375

/**

376

* JUnit 5 extension for lightweight HTTP client testing

377

*/

378

public class DropwizardClientExtension implements DropwizardExtension {

379

380

/**

381

* Create DropwizardClientExtension with JAX-RS resources

382

* @param resources JAX-RS resource instances to register

383

*/

384

public DropwizardClientExtension(Object... resources);

385

386

/**

387

* Get the base URI for HTTP requests to the test server

388

* @return Base URI including scheme, host, and port

389

*/

390

public URI baseUri();

391

392

/**

393

* Get the Jackson ObjectMapper used by the client

394

* @return ObjectMapper instance for JSON processing

395

*/

396

public ObjectMapper getObjectMapper();

397

398

/**

399

* Get the Dropwizard Environment instance

400

* @return Environment with access to metrics, validation, etc.

401

*/

402

public Environment getEnvironment();

403

}

404

```

405

406

**Usage Examples:**

407

408

```java

409

@RegisterExtension

410

public static final DropwizardClientExtension CLIENT =

411

new DropwizardClientExtension(new UserResource(), new OrderResource());

412

413

@Test

414

public void testWithCustomHttpClient() {

415

OkHttpClient httpClient = new OkHttpClient();

416

417

Request request = new Request.Builder()

418

.url(CLIENT.baseUri().resolve("/users").toString())

419

.build();

420

421

try (Response response = httpClient.newCall(request).execute()) {

422

assertThat(response.isSuccessful()).isTrue();

423

}

424

}

425

```

426

427

### DropwizardExtensionsSupport

428

429

Automatic discovery and lifecycle management extension that finds and manages all DropwizardExtension fields in test classes.

430

431

```java { .api }

432

/**

433

* Extension for automatic discovery of DropwizardExtension fields

434

* Implements JUnit 5 lifecycle callbacks for managing extensions

435

*/

436

public class DropwizardExtensionsSupport

437

implements BeforeAllCallback, BeforeEachCallback, AfterAllCallback, AfterEachCallback {

438

439

// Automatically discovers and manages DropwizardExtension fields

440

// No public API - register as extension to enable automatic field discovery

441

}

442

```

443

444

**Usage Examples:**

445

446

```java

447

@ExtendWith(DropwizardExtensionsSupport.class)

448

public class AutoDiscoveryTest {

449

450

// Extensions are automatically discovered and managed

451

public final DropwizardAppExtension<MyConfiguration> app =

452

new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");

453

454

public final ResourceExtension resource = ResourceExtension.builder()

455

.addResource(new UserResource())

456

.build();

457

458

@Test

459

public void testWithAutoDiscovery() {

460

// Extensions are automatically started before this test

461

String response = app.client()

462

.target("http://localhost:" + app.getLocalPort() + "/api/users")

463

.request()

464

.get(String.class);

465

466

assertThat(response).isNotNull();

467

}

468

}

469

```

470

471

## Common Extension Patterns

472

473

### Parameterized Testing

474

475

```java

476

@RegisterExtension

477

public static final DropwizardAppExtension<MyConfiguration> APP =

478

new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");

479

480

@ParameterizedTest

481

@ValueSource(strings = {"/api/users", "/api/orders", "/api/products"})

482

public void testEndpoints(String endpoint) {

483

Response response = APP.client()

484

.target("http://localhost:" + APP.getLocalPort() + endpoint)

485

.request()

486

.get();

487

488

assertThat(response.getStatus()).isEqualTo(200);

489

}

490

```

491

492

### Nested Test Classes

493

494

```java

495

@RegisterExtension

496

public static final DropwizardAppExtension<MyConfiguration> APP =

497

new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");

498

499

@Nested

500

@DisplayName("User API Tests")

501

class UserApiTests {

502

503

@Test

504

public void testGetUsers() {

505

// Test user retrieval

506

}

507

508

@Test

509

public void testCreateUser() {

510

// Test user creation

511

}

512

}

513

514

@Nested

515

@DisplayName("Order API Tests")

516

class OrderApiTests {

517

518

@Test

519

public void testGetOrders() {

520

// Test order retrieval

521

}

522

}

523

```

524

525

### Test Instance Lifecycle

526

527

```java

528

@TestInstance(TestInstance.Lifecycle.PER_CLASS)

529

public class InstancePerClassTest {

530

531

// Extension can be non-static with PER_CLASS lifecycle

532

@RegisterExtension

533

public final DropwizardAppExtension<MyConfiguration> app =

534

new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");

535

536

private TestDataService testDataService;

537

538

@BeforeAll

539

public void setUp() {

540

// Initialize test data service after application starts

541

testDataService = new TestDataService(app.getEnvironment());

542

testDataService.loadTestData();

543

}

544

545

@Test

546

public void testWithPreloadedData() {

547

// Test with data loaded in @BeforeAll

548

}

549

}

550

```

551

552

### Custom Extension Configuration

553

554

```java

555

public class CustomTestExtension extends DropwizardAppExtension<MyConfiguration> {

556

557

public CustomTestExtension() {

558

super(MyApplication.class, createCustomConfig());

559

}

560

561

private static MyConfiguration createCustomConfig() {

562

MyConfiguration config = new MyConfiguration();

563

config.setDatabaseUrl("jdbc:h2:mem:custom_test");

564

config.setLogLevel("DEBUG");

565

return config;

566

}

567

568

@Override

569

protected JerseyClientBuilder clientBuilder() {

570

return super.clientBuilder()

571

.connectTimeout(Duration.ofSeconds(30))

572

.readTimeout(Duration.ofMinutes(2))

573

.register(new RequestLoggingFilter())

574

.register(new ResponseLoggingFilter());

575

}

576

}

577

578

@RegisterExtension

579

public static final CustomTestExtension APP = new CustomTestExtension();

580

```