CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-dropwizard--dropwizard-testing

Comprehensive testing framework and utilities for Dropwizard applications including JUnit 5 extensions, resource testing, and DAO helpers

Pending
Overview
Eval results
Files

junit5-extensions.mddocs/

JUnit 5 Extensions

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.

Capabilities

DropwizardAppExtension

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();

ResourceExtension

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();
}

DAOTestExtension

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();

DropwizardClientExtension

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();
    }
}

DropwizardExtensionsSupport

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();
    }
}

Common Extension Patterns

Parameterized Testing

@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);
}

Nested Test Classes

@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
    }
}

Test Instance Lifecycle

@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
    }
}

Custom Extension Configuration

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

docs

configuration-overrides.md

core-test-support.md

dao-testing.md

index.md

junit5-extensions.md

resource-testing.md

tile.json