0
# Testing
1
2
Comprehensive testing utilities including JUnit 5 extensions for full application testing, resource testing, and database testing.
3
4
## Capabilities
5
6
### Application Testing
7
8
JUnit 5 extension for full application integration testing with real server startup and HTTP client testing.
9
10
```java { .api }
11
package io.dropwizard.testing.junit5;
12
13
public class DropwizardAppExtension<C extends Configuration> implements BeforeAllCallback, AfterAllCallback {
14
/**
15
* Creates an extension for testing the given application class with configuration.
16
*/
17
public static <C extends Configuration> DropwizardAppExtension<C> newInstance(
18
Class<? extends Application<C>> applicationClass,
19
C configuration);
20
21
/**
22
* Creates an extension for testing with a configuration file.
23
*/
24
public static <C extends Configuration> DropwizardAppExtension<C> newInstance(
25
Class<? extends Application<C>> applicationClass,
26
String configPath);
27
28
/**
29
* Returns the application port.
30
*/
31
public int getLocalPort();
32
33
/**
34
* Returns the admin port.
35
*/
36
public int getAdminPort();
37
38
/**
39
* Returns the application instance.
40
*/
41
public Application<C> getApplication();
42
43
/**
44
* Returns the configuration instance.
45
*/
46
public C getConfiguration();
47
48
/**
49
* Returns the environment instance.
50
*/
51
public Environment getEnvironment();
52
53
/**
54
* Returns a JAX-RS client configured for this application.
55
*/
56
public Client client();
57
58
/**
59
* Creates a WebTarget for the given path.
60
*/
61
public WebTarget target(String path);
62
}
63
```
64
65
**Usage Example:**
66
67
```java
68
@ExtendWith(DropwizardExtensionsSupport.class)
69
public class IntegrationTest {
70
private static final DropwizardAppExtension<MyConfiguration> APP =
71
DropwizardAppExtension.newInstance(MyApplication.class,
72
ResourceHelpers.resourceFilePath("test-config.yml"));
73
74
@Test
75
public void testGetUsers() {
76
Response response = APP.target("/users")
77
.request()
78
.get();
79
80
assertThat(response.getStatus()).isEqualTo(200);
81
82
List<User> users = response.readEntity(new GenericType<List<User>>() {});
83
assertThat(users).isNotEmpty();
84
}
85
86
@Test
87
public void testCreateUser() {
88
User newUser = new User("John Doe", "john@example.com");
89
90
Response response = APP.target("/users")
91
.request()
92
.post(Entity.json(newUser));
93
94
assertThat(response.getStatus()).isEqualTo(201);
95
96
User createdUser = response.readEntity(User.class);
97
assertThat(createdUser.getName()).isEqualTo("John Doe");
98
assertThat(createdUser.getId()).isNotNull();
99
}
100
}
101
```
102
103
### Resource Testing
104
105
JUnit 5 extension for testing individual JAX-RS resources in isolation without starting a full application server.
106
107
```java { .api }
108
package io.dropwizard.testing.junit5;
109
110
public class ResourceExtension implements BeforeEachCallback, AfterEachCallback {
111
/**
112
* Creates a resource extension builder.
113
*/
114
public static Builder builder();
115
116
/**
117
* Returns a JAX-RS client for testing.
118
*/
119
public Client client();
120
121
/**
122
* Creates a WebTarget for the given path.
123
*/
124
public WebTarget target(String path);
125
126
/**
127
* Returns the Jersey test environment.
128
*/
129
public JerseyTest getJerseyTest();
130
131
public static class Builder {
132
/**
133
* Adds a resource to test.
134
*/
135
public Builder addResource(Object resource);
136
137
/**
138
* Adds a provider (filter, exception mapper, etc.).
139
*/
140
public Builder addProvider(Object provider);
141
142
/**
143
* Adds a provider class.
144
*/
145
public Builder addProvider(Class<?> providerClass);
146
147
/**
148
* Sets the object mapper for JSON serialization.
149
*/
150
public Builder setMapper(ObjectMapper mapper);
151
152
/**
153
* Builds the resource extension.
154
*/
155
public ResourceExtension build();
156
}
157
}
158
```
159
160
**Usage Example:**
161
162
```java
163
@ExtendWith(DropwizardExtensionsSupport.class)
164
public class UserResourceTest {
165
private final UserService userService = mock(UserService.class);
166
167
private final ResourceExtension resources = ResourceExtension.builder()
168
.addResource(new UserResource(userService))
169
.addProvider(new ValidationExceptionMapper())
170
.build();
171
172
@Test
173
public void testGetUser() {
174
User expectedUser = new User(1L, "John Doe", "john@example.com");
175
when(userService.findById(1L)).thenReturn(Optional.of(expectedUser));
176
177
Response response = resources.target("/users/1")
178
.request()
179
.get();
180
181
assertThat(response.getStatus()).isEqualTo(200);
182
183
User actualUser = response.readEntity(User.class);
184
assertThat(actualUser).isEqualTo(expectedUser);
185
}
186
187
@Test
188
public void testCreateUserValidation() {
189
User invalidUser = new User(null, "", "invalid-email");
190
191
Response response = resources.target("/users")
192
.request()
193
.post(Entity.json(invalidUser));
194
195
assertThat(response.getStatus()).isEqualTo(422); // Unprocessable Entity
196
}
197
198
@Test
199
public void testUserNotFound() {
200
when(userService.findById(999L)).thenReturn(Optional.empty());
201
202
Response response = resources.target("/users/999")
203
.request()
204
.get();
205
206
assertThat(response.getStatus()).isEqualTo(404);
207
}
208
}
209
```
210
211
### Database Testing
212
213
JUnit 5 extension for testing database operations with transaction rollback and data setup/teardown.
214
215
```java { .api }
216
package io.dropwizard.testing.junit5;
217
218
public class DAOTestExtension implements BeforeEachCallback, AfterEachCallback {
219
/**
220
* Creates a DAO test extension for the given database URL and entity classes.
221
*/
222
public static DAOTestExtension newInstance(String url, Class<?>... entities);
223
224
/**
225
* Creates a DAO test extension with a custom data source factory.
226
*/
227
public static DAOTestExtension newInstance(DataSourceFactory dataSourceFactory,
228
Class<?>... entities);
229
230
/**
231
* Returns the session factory for database operations.
232
*/
233
public SessionFactory getSessionFactory();
234
235
/**
236
* Executes code within a transaction that is rolled back after completion.
237
*/
238
public <T> T inTransaction(Function<Session, T> function);
239
240
/**
241
* Executes code within a transaction.
242
*/
243
public void inTransaction(Consumer<Session> consumer);
244
}
245
```
246
247
**Usage Example:**
248
249
```java
250
@ExtendWith(DropwizardExtensionsSupport.class)
251
public class UserDAOTest {
252
private final DAOTestExtension daoTest = DAOTestExtension.newInstance(
253
"jdbc:h2:mem:test", User.class);
254
255
private UserDAO userDAO;
256
257
@BeforeEach
258
public void setUp() {
259
userDAO = new UserDAO(daoTest.getSessionFactory());
260
}
261
262
@Test
263
public void testCreateUser() {
264
User user = daoTest.inTransaction(session -> {
265
User newUser = new User("John Doe", "john@example.com");
266
return userDAO.save(newUser);
267
});
268
269
assertThat(user.getId()).isNotNull();
270
assertThat(user.getName()).isEqualTo("John Doe");
271
}
272
273
@Test
274
public void testFindById() {
275
Long userId = daoTest.inTransaction(session -> {
276
User user = new User("Jane Doe", "jane@example.com");
277
return userDAO.save(user).getId();
278
});
279
280
Optional<User> foundUser = daoTest.inTransaction(session ->
281
userDAO.findById(userId));
282
283
assertThat(foundUser).isPresent();
284
assertThat(foundUser.get().getName()).isEqualTo("Jane Doe");
285
}
286
287
@Test
288
public void testFindAll() {
289
daoTest.inTransaction(session -> {
290
userDAO.save(new User("User 1", "user1@example.com"));
291
userDAO.save(new User("User 2", "user2@example.com"));
292
});
293
294
List<User> users = daoTest.inTransaction(session -> userDAO.findAll());
295
296
assertThat(users).hasSize(2);
297
}
298
}
299
```
300
301
### Client Testing
302
303
JUnit 5 extension for testing HTTP clients and external service interactions.
304
305
```java { .api }
306
package io.dropwizard.testing.junit5;
307
308
public class DropwizardClientExtension implements BeforeEachCallback, AfterEachCallback {
309
/**
310
* Creates a client extension with the given resource.
311
*/
312
public static DropwizardClientExtension newInstance(Object resource);
313
314
/**
315
* Creates a client extension builder.
316
*/
317
public static Builder builder();
318
319
/**
320
* Returns the base URI for the mock server.
321
*/
322
public URI baseUri();
323
324
/**
325
* Creates a WebTarget for the given path.
326
*/
327
public WebTarget target(String path);
328
329
public static class Builder {
330
/**
331
* Adds a resource to the mock server.
332
*/
333
public Builder resource(Object resource);
334
335
/**
336
* Adds a provider to the mock server.
337
*/
338
public Builder provider(Object provider);
339
340
/**
341
* Builds the client extension.
342
*/
343
public DropwizardClientExtension build();
344
}
345
}
346
```
347
348
**Usage Example:**
349
350
```java
351
@ExtendWith(DropwizardExtensionsSupport.class)
352
public class ExternalServiceClientTest {
353
private final DropwizardClientExtension clientRule = DropwizardClientExtension.newInstance(
354
new MockExternalServiceResource());
355
356
private ExternalServiceClient client;
357
358
@BeforeEach
359
public void setUp() {
360
client = new ExternalServiceClient(clientRule.baseUri().toString());
361
}
362
363
@Test
364
public void testGetUserData() {
365
UserData userData = client.getUserData("12345");
366
367
assertThat(userData.getUserId()).isEqualTo("12345");
368
assertThat(userData.getName()).isEqualTo("Mock User");
369
}
370
371
// Mock resource for testing
372
@Path("/api")
373
public static class MockExternalServiceResource {
374
@GET
375
@Path("/users/{id}")
376
@Produces(MediaType.APPLICATION_JSON)
377
public UserData getUser(@PathParam("id") String id) {
378
return new UserData(id, "Mock User", "mock@example.com");
379
}
380
}
381
}
382
```
383
384
### Test Utilities
385
386
Utility classes and methods for common testing scenarios and test data management.
387
388
```java { .api }
389
package io.dropwizard.testing;
390
391
public class ResourceHelpers {
392
/**
393
* Returns the absolute path of a resource file.
394
*/
395
public static String resourceFilePath(String resourceClassPathLocation);
396
397
/**
398
* Returns the content of a resource file as a string.
399
*/
400
public static String fixture(String filename);
401
402
/**
403
* Returns the content of a resource file parsed as JSON.
404
*/
405
public static <T> T jsonFixture(String filename, Class<T> klass);
406
407
/**
408
* Returns the content of a resource file parsed as JSON.
409
*/
410
public static <T> T jsonFixture(String filename, TypeReference<T> type);
411
}
412
413
public class FixtureHelpers {
414
/**
415
* Converts an object to JSON string.
416
*/
417
public static String asJson(Object object) throws JsonProcessingException;
418
419
/**
420
* Parses JSON string to object.
421
*/
422
public static <T> T fromJson(String json, Class<T> klass) throws JsonProcessingException;
423
424
/**
425
* Parses JSON string to object.
426
*/
427
public static <T> T fromJson(String json, TypeReference<T> type) throws JsonProcessingException;
428
}
429
```
430
431
**Usage Example:**
432
433
```java
434
public class JsonTest {
435
private final ObjectMapper mapper = new ObjectMapper();
436
437
@Test
438
public void testUserSerialization() throws Exception {
439
User user = new User("John Doe", "john@example.com");
440
441
String expectedJson = ResourceHelpers.fixture("fixtures/user.json");
442
String actualJson = FixtureHelpers.asJson(user);
443
444
assertThat(actualJson).isEqualTo(expectedJson);
445
}
446
447
@Test
448
public void testUserDeserialization() throws Exception {
449
String json = ResourceHelpers.fixture("fixtures/user.json");
450
User user = FixtureHelpers.fromJson(json, User.class);
451
452
assertThat(user.getName()).isEqualTo("John Doe");
453
assertThat(user.getEmail()).isEqualTo("john@example.com");
454
}
455
}
456
```
457
458
## Testing Patterns
459
460
### Test Configuration
461
462
Creating test-specific configuration files and settings for isolated testing environments.
463
464
```yaml
465
# test-config.yml
466
database:
467
driverClass: org.h2.Driver
468
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
469
username: sa
470
password: ""
471
472
server:
473
applicationConnectors:
474
- type: http
475
port: 0 # Use random available port
476
adminConnectors:
477
- type: http
478
port: 0 # Use random available port
479
480
logging:
481
level: WARN # Reduce log noise during tests
482
```
483
484
### Mocking Dependencies
485
486
Using Mockito and other mocking frameworks to isolate units under test.
487
488
```java
489
@ExtendWith(MockitoExtension.class)
490
public class UserServiceTest {
491
@Mock
492
private UserDAO userDAO;
493
494
@Mock
495
private EmailService emailService;
496
497
@InjectMocks
498
private UserService userService;
499
500
@Test
501
public void testCreateUser() {
502
User newUser = new User("John Doe", "john@example.com");
503
User savedUser = new User(1L, "John Doe", "john@example.com");
504
505
when(userDAO.save(any(User.class))).thenReturn(savedUser);
506
507
User result = userService.createUser(newUser);
508
509
assertThat(result.getId()).isEqualTo(1L);
510
verify(emailService).sendWelcomeEmail(savedUser);
511
}
512
}
513
```