Comprehensive testing framework and utilities for Dropwizard applications including JUnit 5 extensions, resource testing, and DAO helpers
—
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.
JUnit 5 extension for complete Dropwizard application testing with automatic lifecycle management, HTTP client setup, and access to all application components.
/**
* JUnit 5 extension for full Dropwizard application testing
* @param <C> Configuration type extending Configuration
*/
public class DropwizardAppExtension<C extends Configuration>
implements DropwizardExtension, BeforeAllCallback, AfterAllCallback {
// Constructor variants matching DropwizardTestSupport
/**
* Create extension with application class and configuration file
* @param applicationClass Dropwizard application class
* @param configPath Path to configuration file
* @param configOverrides Configuration overrides for testing
*/
public DropwizardAppExtension(Class<? extends Application<C>> applicationClass,
String configPath,
ConfigOverride... configOverrides);
/**
* Create extension with application class and configuration object
* @param applicationClass Dropwizard application class
* @param configuration Pre-built configuration instance
* @param configOverrides Configuration overrides for testing
*/
public DropwizardAppExtension(Class<? extends Application<C>> applicationClass,
C configuration,
ConfigOverride... configOverrides);
// Application access methods
/**
* Get the application configuration instance
* @return Configuration object used by the application
*/
public C getConfiguration();
/**
* Get the running Dropwizard application instance
* @return Application instance with full type information
*/
public <A extends Application<C>> A getApplication();
/**
* Get the Dropwizard runtime environment
* @return Environment instance with access to metrics, validation, etc.
*/
public Environment getEnvironment();
/**
* Get the Jackson ObjectMapper used by the application
* @return ObjectMapper for JSON/YAML processing
*/
public ObjectMapper getObjectMapper();
// Network access methods
/**
* Get the main application HTTP port
* @return Port number for application endpoints
*/
public int getLocalPort();
/**
* Get the admin interface HTTP port
* @return Port number for admin endpoints
*/
public int getAdminPort();
/**
* Get the port for a specific connector by index
* @param connectorIndex Zero-based connector index
* @return Port number for the specified connector
*/
public int getPort(int connectorIndex);
// HTTP testing support
/**
* Get a configured HTTP client for testing application endpoints
* Uses default timeouts and response buffering for reliable testing
* @return JAX-RS Client configured for testing
*/
public Client client();
/**
* Get the underlying DropwizardTestSupport instance
* @return DropwizardTestSupport managing the application lifecycle
*/
public DropwizardTestSupport<C> getTestSupport();
// Configuration and extension methods
/**
* Add a lifecycle listener for application events
* @param listener ServiceListener instance for handling events
* @return This DropwizardAppExtension instance for chaining
*/
public DropwizardAppExtension<C> addListener(ServiceListener<C> listener);
/**
* Add a managed object to the application lifecycle
* @param managed Managed object to start/stop with application
* @return This DropwizardAppExtension instance for chaining
*/
public DropwizardAppExtension<C> manage(Managed managed);
/**
* Create a customizable Jersey client builder
* Override this method to customize HTTP client configuration
* @return JerseyClientBuilder for custom client setup
*/
protected JerseyClientBuilder clientBuilder();
}Usage Examples:
// Basic application testing
@RegisterExtension
public static final DropwizardAppExtension<MyConfiguration> APP =
new DropwizardAppExtension<>(
MyApplication.class,
ResourceHelpers.resourceFilePath("test-config.yml")
);
@Test
public void testApplicationEndpoint() {
String response = APP.client()
.target("http://localhost:" + APP.getLocalPort() + "/api/health")
.request()
.get(String.class);
assertThat(response).contains("healthy");
}
// With configuration overrides
@RegisterExtension
public static final DropwizardAppExtension<MyConfiguration> APP =
new DropwizardAppExtension<>(
MyApplication.class,
ResourceHelpers.resourceFilePath("test-config.yml"),
ConfigOverride.randomPorts(),
ConfigOverride.config("database.url", "jdbc:h2:mem:test")
);
// With pre-built configuration
public static MyConfiguration createTestConfiguration() {
MyConfiguration config = new MyConfiguration();
config.setDatabaseUrl("jdbc:h2:mem:test");
config.getServerFactory().setApplicationConnectors(/* custom connectors */);
return config;
}
@RegisterExtension
public static final DropwizardAppExtension<MyConfiguration> APP =
new DropwizardAppExtension<>(MyApplication.class, createTestConfiguration());
// With lifecycle listeners
@RegisterExtension
public static final DropwizardAppExtension<MyConfiguration> APP =
new DropwizardAppExtension<MyConfiguration>(
MyApplication.class,
ResourceHelpers.resourceFilePath("test-config.yml")
).addListener(new ServiceListener<MyConfiguration>() {
@Override
public void onRun(MyConfiguration configuration,
Environment environment,
DropwizardTestSupport<MyConfiguration> rule) {
// Initialize test data, mock external services, etc.
TestDataLoader.loadTestData(environment.getApplicationContext());
}
});
// Testing with custom HTTP client configuration
public class CustomAppExtension extends DropwizardAppExtension<MyConfiguration> {
public CustomAppExtension() {
super(MyApplication.class, ResourceHelpers.resourceFilePath("test-config.yml"));
}
@Override
protected JerseyClientBuilder clientBuilder() {
return super.clientBuilder()
.connectTimeout(Duration.ofSeconds(10))
.readTimeout(Duration.ofSeconds(30))
.register(new CustomClientFilter());
}
}
@RegisterExtension
public static final CustomAppExtension APP = new CustomAppExtension();JUnit 5 extension for isolated JAX-RS resource testing without full application bootstrap, providing fast unit testing of individual REST endpoints.
/**
* JUnit 5 extension for isolated JAX-RS resource testing
*/
public class ResourceExtension implements DropwizardExtension {
/**
* Create a new ResourceExtension builder for configuration
* @return Builder instance for fluent configuration
*/
public static Builder builder();
/**
* Get a JAX-RS WebTarget for making HTTP requests to resources
* @param path Path to append to base URI
* @return WebTarget for the specified path
*/
public WebTarget target(String path);
/**
* Get the underlying JAX-RS Client for advanced HTTP operations
* @return JAX-RS Client instance
*/
public Client client();
/**
* Get the underlying JerseyTest instance for advanced testing
* @return JerseyTest instance managing the test environment
*/
public JerseyTest getJerseyTest();
/**
* Get the Bean Validator used by the resource testing environment
* @return Validator instance for bean validation
*/
public Validator getValidator();
/**
* Get the Jackson ObjectMapper used for JSON serialization/deserialization
* @return ObjectMapper instance
*/
public ObjectMapper getObjectMapper();
/**
* Get the client configurator for custom client setup
* @return Consumer for ClientConfig customization
*/
public Consumer<ClientConfig> getClientConfigurator();
}Usage Examples:
// Basic resource testing
@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
.addResource(new UserResource())
.build();
@Test
public void testGetUsers() {
List<User> users = RESOURCE.target("/users")
.request(MediaType.APPLICATION_JSON)
.get(new GenericType<List<User>>() {});
assertThat(users).isNotEmpty();
}
// With dependency injection
UserService userService = mock(UserService.class);
@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
.addResource(new UserResource(userService))
.build();
@Test
public void testCreateUser() {
when(userService.create(any(User.class)))
.thenReturn(new User(1L, "John", "john@example.com"));
User newUser = new User("John", "john@example.com");
Response response = RESOURCE.target("/users")
.request()
.post(Entity.json(newUser));
assertThat(response.getStatus()).isEqualTo(201);
User createdUser = response.readEntity(User.class);
assertThat(createdUser.getId()).isNotNull();
}JUnit 5 extension for Hibernate DAO testing with automated database setup, transaction management, and cleanup.
/**
* JUnit 5 extension for Hibernate DAO testing
*/
public class DAOTestExtension implements DropwizardExtension, BeforeAllCallback, AfterAllCallback {
/**
* Create a new DAOTestExtension builder for configuration
* @return Builder instance for fluent database configuration
*/
public static Builder newBuilder();
/**
* Get the Hibernate SessionFactory for database operations
* @return SessionFactory instance for creating sessions
*/
public SessionFactory getSessionFactory();
/**
* Execute code within a database transaction with return value
* @param call Callable to execute within transaction
* @return Result of the callable execution
* @throws Exception if the callable execution fails
*/
public <T> T inTransaction(Callable<T> call) throws Exception;
/**
* Execute code within a database transaction without return value
* @param action Runnable to execute within transaction
* @throws Exception if the action execution fails
*/
public void inTransaction(Runnable action) throws Exception;
}Usage Examples:
// Basic DAO testing
@RegisterExtension
public static final DAOTestExtension DAO_TEST = DAOTestExtension.newBuilder()
.addEntityClass(User.class)
.addEntityClass(Order.class)
.build();
@Test
public void testUserDAO() throws Exception {
UserDAO userDAO = new UserDAO(DAO_TEST.getSessionFactory());
User user = DAO_TEST.inTransaction(() -> {
User newUser = new User("Alice", "alice@example.com");
return userDAO.save(newUser);
});
assertThat(user.getId()).isNotNull();
}
// With custom database configuration
@RegisterExtension
public static final DAOTestExtension DAO_TEST = DAOTestExtension.newBuilder()
.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
.addEntityClass(User.class)
.setShowSql(true)
.setHbm2DdlAuto("create-drop")
.build();JUnit 5 extension for lightweight HTTP client testing with minimal Dropwizard setup.
/**
* JUnit 5 extension for lightweight HTTP client testing
*/
public class DropwizardClientExtension implements DropwizardExtension {
/**
* Create DropwizardClientExtension with JAX-RS resources
* @param resources JAX-RS resource instances to register
*/
public DropwizardClientExtension(Object... resources);
/**
* Get the base URI for HTTP requests to the test server
* @return Base URI including scheme, host, and port
*/
public URI baseUri();
/**
* Get the Jackson ObjectMapper used by the client
* @return ObjectMapper instance for JSON processing
*/
public ObjectMapper getObjectMapper();
/**
* Get the Dropwizard Environment instance
* @return Environment with access to metrics, validation, etc.
*/
public Environment getEnvironment();
}Usage Examples:
@RegisterExtension
public static final DropwizardClientExtension CLIENT =
new DropwizardClientExtension(new UserResource(), new OrderResource());
@Test
public void testWithCustomHttpClient() {
OkHttpClient httpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(CLIENT.baseUri().resolve("/users").toString())
.build();
try (Response response = httpClient.newCall(request).execute()) {
assertThat(response.isSuccessful()).isTrue();
}
}Automatic discovery and lifecycle management extension that finds and manages all DropwizardExtension fields in test classes.
/**
* Extension for automatic discovery of DropwizardExtension fields
* Implements JUnit 5 lifecycle callbacks for managing extensions
*/
public class DropwizardExtensionsSupport
implements BeforeAllCallback, BeforeEachCallback, AfterAllCallback, AfterEachCallback {
// Automatically discovers and manages DropwizardExtension fields
// No public API - register as extension to enable automatic field discovery
}Usage Examples:
@ExtendWith(DropwizardExtensionsSupport.class)
public class AutoDiscoveryTest {
// Extensions are automatically discovered and managed
public final DropwizardAppExtension<MyConfiguration> app =
new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");
public final ResourceExtension resource = ResourceExtension.builder()
.addResource(new UserResource())
.build();
@Test
public void testWithAutoDiscovery() {
// Extensions are automatically started before this test
String response = app.client()
.target("http://localhost:" + app.getLocalPort() + "/api/users")
.request()
.get(String.class);
assertThat(response).isNotNull();
}
}@RegisterExtension
public static final DropwizardAppExtension<MyConfiguration> APP =
new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");
@ParameterizedTest
@ValueSource(strings = {"/api/users", "/api/orders", "/api/products"})
public void testEndpoints(String endpoint) {
Response response = APP.client()
.target("http://localhost:" + APP.getLocalPort() + endpoint)
.request()
.get();
assertThat(response.getStatus()).isEqualTo(200);
}@RegisterExtension
public static final DropwizardAppExtension<MyConfiguration> APP =
new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");
@Nested
@DisplayName("User API Tests")
class UserApiTests {
@Test
public void testGetUsers() {
// Test user retrieval
}
@Test
public void testCreateUser() {
// Test user creation
}
}
@Nested
@DisplayName("Order API Tests")
class OrderApiTests {
@Test
public void testGetOrders() {
// Test order retrieval
}
}@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class InstancePerClassTest {
// Extension can be non-static with PER_CLASS lifecycle
@RegisterExtension
public final DropwizardAppExtension<MyConfiguration> app =
new DropwizardAppExtension<>(MyApplication.class, "test-config.yml");
private TestDataService testDataService;
@BeforeAll
public void setUp() {
// Initialize test data service after application starts
testDataService = new TestDataService(app.getEnvironment());
testDataService.loadTestData();
}
@Test
public void testWithPreloadedData() {
// Test with data loaded in @BeforeAll
}
}public class CustomTestExtension extends DropwizardAppExtension<MyConfiguration> {
public CustomTestExtension() {
super(MyApplication.class, createCustomConfig());
}
private static MyConfiguration createCustomConfig() {
MyConfiguration config = new MyConfiguration();
config.setDatabaseUrl("jdbc:h2:mem:custom_test");
config.setLogLevel("DEBUG");
return config;
}
@Override
protected JerseyClientBuilder clientBuilder() {
return super.clientBuilder()
.connectTimeout(Duration.ofSeconds(30))
.readTimeout(Duration.ofMinutes(2))
.register(new RequestLoggingFilter())
.register(new ResponseLoggingFilter());
}
}
@RegisterExtension
public static final CustomTestExtension APP = new CustomTestExtension();Install with Tessl CLI
npx tessl i tessl/maven-io-dropwizard--dropwizard-testing