Java framework for developing ops-friendly, high-performance, RESTful web applications
—
Comprehensive testing utilities including JUnit 5 extensions for full application testing, resource testing, and database testing.
JUnit 5 extension for full application integration testing with real server startup and HTTP client testing.
package io.dropwizard.testing.junit5;
public class DropwizardAppExtension<C extends Configuration> implements BeforeAllCallback, AfterAllCallback {
/**
* Creates an extension for testing the given application class with configuration.
*/
public static <C extends Configuration> DropwizardAppExtension<C> newInstance(
Class<? extends Application<C>> applicationClass,
C configuration);
/**
* Creates an extension for testing with a configuration file.
*/
public static <C extends Configuration> DropwizardAppExtension<C> newInstance(
Class<? extends Application<C>> applicationClass,
String configPath);
/**
* Returns the application port.
*/
public int getLocalPort();
/**
* Returns the admin port.
*/
public int getAdminPort();
/**
* Returns the application instance.
*/
public Application<C> getApplication();
/**
* Returns the configuration instance.
*/
public C getConfiguration();
/**
* Returns the environment instance.
*/
public Environment getEnvironment();
/**
* Returns a JAX-RS client configured for this application.
*/
public Client client();
/**
* Creates a WebTarget for the given path.
*/
public WebTarget target(String path);
}Usage Example:
@ExtendWith(DropwizardExtensionsSupport.class)
public class IntegrationTest {
private static final DropwizardAppExtension<MyConfiguration> APP =
DropwizardAppExtension.newInstance(MyApplication.class,
ResourceHelpers.resourceFilePath("test-config.yml"));
@Test
public void testGetUsers() {
Response response = APP.target("/users")
.request()
.get();
assertThat(response.getStatus()).isEqualTo(200);
List<User> users = response.readEntity(new GenericType<List<User>>() {});
assertThat(users).isNotEmpty();
}
@Test
public void testCreateUser() {
User newUser = new User("John Doe", "john@example.com");
Response response = APP.target("/users")
.request()
.post(Entity.json(newUser));
assertThat(response.getStatus()).isEqualTo(201);
User createdUser = response.readEntity(User.class);
assertThat(createdUser.getName()).isEqualTo("John Doe");
assertThat(createdUser.getId()).isNotNull();
}
}JUnit 5 extension for testing individual JAX-RS resources in isolation without starting a full application server.
package io.dropwizard.testing.junit5;
public class ResourceExtension implements BeforeEachCallback, AfterEachCallback {
/**
* Creates a resource extension builder.
*/
public static Builder builder();
/**
* Returns a JAX-RS client for testing.
*/
public Client client();
/**
* Creates a WebTarget for the given path.
*/
public WebTarget target(String path);
/**
* Returns the Jersey test environment.
*/
public JerseyTest getJerseyTest();
public static class Builder {
/**
* Adds a resource to test.
*/
public Builder addResource(Object resource);
/**
* Adds a provider (filter, exception mapper, etc.).
*/
public Builder addProvider(Object provider);
/**
* Adds a provider class.
*/
public Builder addProvider(Class<?> providerClass);
/**
* Sets the object mapper for JSON serialization.
*/
public Builder setMapper(ObjectMapper mapper);
/**
* Builds the resource extension.
*/
public ResourceExtension build();
}
}Usage Example:
@ExtendWith(DropwizardExtensionsSupport.class)
public class UserResourceTest {
private final UserService userService = mock(UserService.class);
private final ResourceExtension resources = ResourceExtension.builder()
.addResource(new UserResource(userService))
.addProvider(new ValidationExceptionMapper())
.build();
@Test
public void testGetUser() {
User expectedUser = new User(1L, "John Doe", "john@example.com");
when(userService.findById(1L)).thenReturn(Optional.of(expectedUser));
Response response = resources.target("/users/1")
.request()
.get();
assertThat(response.getStatus()).isEqualTo(200);
User actualUser = response.readEntity(User.class);
assertThat(actualUser).isEqualTo(expectedUser);
}
@Test
public void testCreateUserValidation() {
User invalidUser = new User(null, "", "invalid-email");
Response response = resources.target("/users")
.request()
.post(Entity.json(invalidUser));
assertThat(response.getStatus()).isEqualTo(422); // Unprocessable Entity
}
@Test
public void testUserNotFound() {
when(userService.findById(999L)).thenReturn(Optional.empty());
Response response = resources.target("/users/999")
.request()
.get();
assertThat(response.getStatus()).isEqualTo(404);
}
}JUnit 5 extension for testing database operations with transaction rollback and data setup/teardown.
package io.dropwizard.testing.junit5;
public class DAOTestExtension implements BeforeEachCallback, AfterEachCallback {
/**
* Creates a DAO test extension for the given database URL and entity classes.
*/
public static DAOTestExtension newInstance(String url, Class<?>... entities);
/**
* Creates a DAO test extension with a custom data source factory.
*/
public static DAOTestExtension newInstance(DataSourceFactory dataSourceFactory,
Class<?>... entities);
/**
* Returns the session factory for database operations.
*/
public SessionFactory getSessionFactory();
/**
* Executes code within a transaction that is rolled back after completion.
*/
public <T> T inTransaction(Function<Session, T> function);
/**
* Executes code within a transaction.
*/
public void inTransaction(Consumer<Session> consumer);
}Usage Example:
@ExtendWith(DropwizardExtensionsSupport.class)
public class UserDAOTest {
private final DAOTestExtension daoTest = DAOTestExtension.newInstance(
"jdbc:h2:mem:test", User.class);
private UserDAO userDAO;
@BeforeEach
public void setUp() {
userDAO = new UserDAO(daoTest.getSessionFactory());
}
@Test
public void testCreateUser() {
User user = daoTest.inTransaction(session -> {
User newUser = new User("John Doe", "john@example.com");
return userDAO.save(newUser);
});
assertThat(user.getId()).isNotNull();
assertThat(user.getName()).isEqualTo("John Doe");
}
@Test
public void testFindById() {
Long userId = daoTest.inTransaction(session -> {
User user = new User("Jane Doe", "jane@example.com");
return userDAO.save(user).getId();
});
Optional<User> foundUser = daoTest.inTransaction(session ->
userDAO.findById(userId));
assertThat(foundUser).isPresent();
assertThat(foundUser.get().getName()).isEqualTo("Jane Doe");
}
@Test
public void testFindAll() {
daoTest.inTransaction(session -> {
userDAO.save(new User("User 1", "user1@example.com"));
userDAO.save(new User("User 2", "user2@example.com"));
});
List<User> users = daoTest.inTransaction(session -> userDAO.findAll());
assertThat(users).hasSize(2);
}
}JUnit 5 extension for testing HTTP clients and external service interactions.
package io.dropwizard.testing.junit5;
public class DropwizardClientExtension implements BeforeEachCallback, AfterEachCallback {
/**
* Creates a client extension with the given resource.
*/
public static DropwizardClientExtension newInstance(Object resource);
/**
* Creates a client extension builder.
*/
public static Builder builder();
/**
* Returns the base URI for the mock server.
*/
public URI baseUri();
/**
* Creates a WebTarget for the given path.
*/
public WebTarget target(String path);
public static class Builder {
/**
* Adds a resource to the mock server.
*/
public Builder resource(Object resource);
/**
* Adds a provider to the mock server.
*/
public Builder provider(Object provider);
/**
* Builds the client extension.
*/
public DropwizardClientExtension build();
}
}Usage Example:
@ExtendWith(DropwizardExtensionsSupport.class)
public class ExternalServiceClientTest {
private final DropwizardClientExtension clientRule = DropwizardClientExtension.newInstance(
new MockExternalServiceResource());
private ExternalServiceClient client;
@BeforeEach
public void setUp() {
client = new ExternalServiceClient(clientRule.baseUri().toString());
}
@Test
public void testGetUserData() {
UserData userData = client.getUserData("12345");
assertThat(userData.getUserId()).isEqualTo("12345");
assertThat(userData.getName()).isEqualTo("Mock User");
}
// Mock resource for testing
@Path("/api")
public static class MockExternalServiceResource {
@GET
@Path("/users/{id}")
@Produces(MediaType.APPLICATION_JSON)
public UserData getUser(@PathParam("id") String id) {
return new UserData(id, "Mock User", "mock@example.com");
}
}
}Utility classes and methods for common testing scenarios and test data management.
package io.dropwizard.testing;
public class ResourceHelpers {
/**
* Returns the absolute path of a resource file.
*/
public static String resourceFilePath(String resourceClassPathLocation);
/**
* Returns the content of a resource file as a string.
*/
public static String fixture(String filename);
/**
* Returns the content of a resource file parsed as JSON.
*/
public static <T> T jsonFixture(String filename, Class<T> klass);
/**
* Returns the content of a resource file parsed as JSON.
*/
public static <T> T jsonFixture(String filename, TypeReference<T> type);
}
public class FixtureHelpers {
/**
* Converts an object to JSON string.
*/
public static String asJson(Object object) throws JsonProcessingException;
/**
* Parses JSON string to object.
*/
public static <T> T fromJson(String json, Class<T> klass) throws JsonProcessingException;
/**
* Parses JSON string to object.
*/
public static <T> T fromJson(String json, TypeReference<T> type) throws JsonProcessingException;
}Usage Example:
public class JsonTest {
private final ObjectMapper mapper = new ObjectMapper();
@Test
public void testUserSerialization() throws Exception {
User user = new User("John Doe", "john@example.com");
String expectedJson = ResourceHelpers.fixture("fixtures/user.json");
String actualJson = FixtureHelpers.asJson(user);
assertThat(actualJson).isEqualTo(expectedJson);
}
@Test
public void testUserDeserialization() throws Exception {
String json = ResourceHelpers.fixture("fixtures/user.json");
User user = FixtureHelpers.fromJson(json, User.class);
assertThat(user.getName()).isEqualTo("John Doe");
assertThat(user.getEmail()).isEqualTo("john@example.com");
}
}Creating test-specific configuration files and settings for isolated testing environments.
# test-config.yml
database:
driverClass: org.h2.Driver
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
username: sa
password: ""
server:
applicationConnectors:
- type: http
port: 0 # Use random available port
adminConnectors:
- type: http
port: 0 # Use random available port
logging:
level: WARN # Reduce log noise during testsUsing Mockito and other mocking frameworks to isolate units under test.
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserDAO userDAO;
@Mock
private EmailService emailService;
@InjectMocks
private UserService userService;
@Test
public void testCreateUser() {
User newUser = new User("John Doe", "john@example.com");
User savedUser = new User(1L, "John Doe", "john@example.com");
when(userDAO.save(any(User.class))).thenReturn(savedUser);
User result = userService.createUser(newUser);
assertThat(result.getId()).isEqualTo(1L);
verify(emailService).sendWelcomeEmail(savedUser);
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-dropwizard--dropwizard-project