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

resource-testing.mddocs/

Resource Testing

Lightweight JAX-RS resource testing utilities providing isolated testing environment without full Dropwizard application bootstrap. Perfect for unit testing individual REST endpoints with minimal overhead and fast execution.

Capabilities

Resource

Core utility class for creating isolated JAX-RS resource testing environments with configurable Jackson ObjectMapper, Bean Validation, and Jersey providers.

/**
 * Utility class for isolated JAX-RS resource testing
 */
public class Resource {
    
    /**
     * Create a new Resource 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();
    
    // Lifecycle methods
    /**
     * Initialize the resource testing environment before tests
     * @throws Exception if initialization fails
     */
    public void before() throws Exception;
    
    /**
     * Cleanup the resource testing environment after tests
     * @throws Exception if cleanup fails
     */
    public void after() throws Exception;
}

Resource.Builder

Fluent builder for configuring Resource testing environments with custom ObjectMapper, validators, providers, and Jersey settings.

/**
 * Fluent builder for Resource configuration
 */
public static class Builder<B extends Builder<B>> {
    
    // Resource configuration
    /**
     * Add a JAX-RS resource instance to the testing environment
     * @param resource Resource instance to add
     * @return Builder instance for chaining
     */
    public B addResource(Object resource);
    
    /**
     * Add a JAX-RS resource using a supplier for lazy initialization
     * @param resourceSupplier Supplier providing the resource instance
     * @return Builder instance for chaining
     */
    public B addResource(Supplier<Object> resourceSupplier);
    
    // Provider configuration
    /**
     * Add a JAX-RS provider class to the testing environment
     * @param klass Provider class to register
     * @return Builder instance for chaining
     */
    public B addProvider(Class<?> klass);
    
    /**
     * Add a JAX-RS provider instance to the testing environment
     * @param provider Provider instance to register
     * @return Builder instance for chaining
     */
    public B addProvider(Object provider);
    
    // Component customization
    /**
     * Set a custom Jackson ObjectMapper for JSON processing
     * @param mapper Custom ObjectMapper instance
     * @return Builder instance for chaining
     */
    public B setMapper(ObjectMapper mapper);
    
    /**
     * Set a custom MetricRegistry for metrics collection
     * @param metricRegistry Custom MetricRegistry instance
     * @return Builder instance for chaining
     */
    public B setMetricRegistry(MetricRegistry metricRegistry);
    
    /**
     * Set a custom Bean Validator for request/response validation
     * @param validator Custom Validator instance
     * @return Builder instance for chaining
     */
    public B setValidator(Validator validator);
    
    // Jersey configuration
    /**
     * Set a custom client configurator for HTTP client setup
     * @param clientConfigurator Consumer for ClientConfig customization
     * @return Builder instance for chaining
     */
    public B setClientConfigurator(Consumer<ClientConfig> clientConfigurator);
    
    /**
     * Add a Jersey property to the testing environment
     * @param property Property name
     * @param value Property value
     * @return Builder instance for chaining
     */
    public B addProperty(String property, Object value);
    
    /**
     * Set a custom TestContainerFactory for Jersey testing
     * @param factory Custom TestContainerFactory instance
     * @return Builder instance for chaining
     */
    public B setTestContainerFactory(TestContainerFactory factory);
    
    /**
     * Configure whether to register default exception mappers
     * @param value true to register default exception mappers, false otherwise
     * @return Builder instance for chaining
     */
    public B setRegisterDefaultExceptionMappers(boolean value);
    
    /**
     * Configure whether to bootstrap Logback logging
     * @param value true to bootstrap logging, false otherwise
     * @return Builder instance for chaining
     */
    public B bootstrapLogging(boolean value);
    
    /**
     * Build the configured Resource instance
     * @return Configured Resource instance ready for testing
     */
    public Resource build();
}

Usage Examples:

// Basic resource testing
@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
    .addResource(new UserResource())
    .build();

@Test
public void testGetUser() {
    User user = RESOURCE.target("/users/123")
        .request(MediaType.APPLICATION_JSON)
        .get(User.class);
    
    assertThat(user.getId()).isEqualTo(123);
}

// With custom ObjectMapper and providers
@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
    .addResource(new UserResource())
    .addProvider(new CustomExceptionMapper())
    .addProvider(new ValidationFeature())
    .setMapper(createCustomObjectMapper())
    .build();

// With multiple resources and shared dependencies
UserService userService = mock(UserService.class);
EmailService emailService = mock(EmailService.class);

@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
    .addResource(new UserResource(userService))
    .addResource(new EmailResource(emailService))
    .addProvider(new AuthenticationFilter())
    .setValidator(Validation.buildDefaultValidatorFactory().getValidator())
    .build();

// Advanced configuration with custom client setup
@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
    .addResource(new ApiResource())
    .setClientConfigurator(clientConfig -> {
        clientConfig.register(new LoggingFeature());
        clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 5000);
        clientConfig.property(ClientProperties.READ_TIMEOUT, 10000);
    })
    .addProperty(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true)
    .build();

@Test
public void testResourceValidation() {
    Response response = RESOURCE.target("/api/users")
        .request()
        .post(Entity.json("{ \"invalid\": \"data\" }"));
    
    assertThat(response.getStatus()).isEqualTo(400);
    
    ValidationErrorResponse error = response.readEntity(ValidationErrorResponse.class);
    assertThat(error.getErrors()).isNotEmpty();
}

// Testing with different content types
@Test
public void testContentNegotiation() {
    // JSON request/response
    User jsonUser = RESOURCE.target("/users/123")
        .request(MediaType.APPLICATION_JSON)
        .get(User.class);
    
    // XML request/response
    User xmlUser = RESOURCE.target("/users/123")
        .request(MediaType.APPLICATION_XML)
        .get(User.class);
    
    assertThat(jsonUser).isEqualTo(xmlUser);
}

// Testing error handling
@Test
public void testErrorHandling() {
    Response response = RESOURCE.target("/users/999")
        .request()
        .get();
    
    assertThat(response.getStatus()).isEqualTo(404);
    
    ErrorResponse error = response.readEntity(ErrorResponse.class);
    assertThat(error.getMessage()).contains("User not found");
}

DropwizardClient

Lightweight HTTP client testing utility providing minimal Dropwizard setup for testing HTTP interactions without full application bootstrap.

/**
 * Lightweight HTTP client for testing REST endpoints
 */
public class DropwizardClient {
    
    /**
     * Create DropwizardClient with JAX-RS resources
     * @param resources JAX-RS resource instances to register
     */
    public DropwizardClient(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();
    
    // Lifecycle methods
    /**
     * Initialize the client testing environment before tests
     * @throws Exception if initialization fails
     */
    public void before() throws Exception;
    
    /**
     * Cleanup the client testing environment after tests
     * @throws Exception if cleanup fails
     */
    public void after() throws Exception;
}

Usage Examples:

// Manual client setup
DropwizardClient client = new DropwizardClient(
    new UserResource(),
    new OrderResource()
);

@BeforeEach
public void setUp() throws Exception {
    client.before();
}

@AfterEach
public void tearDown() throws Exception {
    client.after();
}

@Test
public void testWithHttpClient() {
    URI baseUri = client.baseUri();
    
    // Use any HTTP client library
    String response = HttpClient.newHttpClient()
        .send(HttpRequest.newBuilder()
            .uri(baseUri.resolve("/users"))
            .build(), 
            HttpResponse.BodyHandlers.ofString())
        .body();
    
    assertThat(response).contains("users");
}

// With OkHttp client
@Test  
public void testWithOkHttp() {
    OkHttpClient httpClient = new OkHttpClient();
    Request request = new Request.Builder()
        .url(client.baseUri().resolve("/users").toString())
        .build();
    
    try (okhttp3.Response response = httpClient.newCall(request).execute()) {
        assertThat(response.isSuccessful()).isTrue();
        String body = response.body().string();
        assertThat(body).isNotNull();
    }
}

Common Testing Patterns

Resource Validation Testing

@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
    .addResource(new UserResource())
    .setRegisterDefaultExceptionMappers(true)
    .build();

@Test
public void testValidationErrors() {
    // Invalid user data
    User invalidUser = new User();
    invalidUser.setEmail("invalid-email");
    
    Response response = RESOURCE.target("/users")
        .request()
        .post(Entity.json(invalidUser));
    
    assertThat(response.getStatus()).isEqualTo(422);
    
    ValidationErrorMessage error = response.readEntity(ValidationErrorMessage.class);
    assertThat(error.getErrors()).containsKey("email");
}

Exception Mapper Testing

@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
    .addResource(new UserResource())
    .addProvider(new CustomExceptionMapper())
    .build();

@Test
public void testCustomExceptionHandling() {
    Response response = RESOURCE.target("/users/trigger-custom-exception")
        .request()
        .get();
    
    assertThat(response.getStatus()).isEqualTo(418);
    assertThat(response.getHeaderString("X-Custom-Error")).isEqualTo("true");
}

Authentication Filter Testing

@RegisterExtension
public static final ResourceExtension RESOURCE = ResourceExtension.builder()
    .addResource(new SecureResource())
    .addProvider(new AuthenticationFilter())
    .build();

@Test
public void testAuthenticationRequired() {
    Response response = RESOURCE.target("/secure/data")
        .request()
        .get();
    
    assertThat(response.getStatus()).isEqualTo(401);
}

@Test
public void testAuthenticatedAccess() {
    Response response = RESOURCE.target("/secure/data")
        .request()
        .header("Authorization", "Bearer valid-token")
        .get();
    
    assertThat(response.getStatus()).isEqualTo(200);
}

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