General test tools¶
Test framework-agnostic tools. Useful when:
- There is no extensions for your test framework
- Assertions must be performed after test app shutdown (or before startup)
Test utils:
TestSupport
- root utilities class, providing easy access to other helpersDropwizardTestSupport
- dropwizard native support for full integration testsGuiceyTestSupport
- guice context-only integration tests (without starting web part)ClientSupport
- web client helper (useful for calling application urls)
Important
TestSupport
assumed to be used as a universal shortcut: everything could be created/executed through it
so just type TestSupport.
and look available methods - no need to remember other classes.
Web app¶
Core DropwizardTestSupport class used to run complete application for testing:
DropwizardTestSupport support = TestSupport.webApp(App.class, "path/to/test-config.yml");
// OR for custom configuration - new DropwizardTestSupport(App.class, "path/to/test-config.yml");
// start
support.before();
// helpers
support.getEnvironment();
support.getConfiguration();
support.getApplication();
// stop
support.after();
Provides two lifecycle methods: before()
and after()
and utilities to access context environment and configuration objects.
See constructor for advanced configuration options.
Core app¶
GuiceyTestSupport
is an inheritor of DropwizardTestSupport
(could be casted) starting only
guice context without web part. Provides additional utility methods:
GuiceyTestSupport support = TestSupport.coreApp(App.class, "path/to/test-config.yml");
// OR for custom configuration - new GuiceyTestSupport(App.class, "path/to/test-config.yml");
// start
support.before();
// additional method
support.getBean(Key/Class);
// stop
support.after();
Also provide shortcut .run(callback)
method as an alternative to manual before()
and after()
calls.
Client¶
ClientSupport
is a JerseyClient
aware of dropwizard configuration, so you can easily call admin/main/rest urls.
Creation:
ClientSupport client = TestSupport.webClient(support);
where support is DropwizardTestSupport
or GuiceyTestSupport
(in later case it could be used only as generic client for calling external urls).
Example usage:
// GET {rest path}/some
client.targetRest("some").request().buildGet().invoke()
// GET {main context path}/servlet
client.targetMain("servlet").request().buildGet().invoke()
// GET {admin context path}/adminServlet
client.targetAdmin("adminServlet").request().buildGet().invoke()
// General external url call
client.target("https://google.com").request().buildGet().invoke()
Tip
All methods above accepts any number of strings which would be automatically combined into correct path:
client.targetRest("some", "other/", "/part")
As you can see, test code is abstracted from actual configuration: it may be default or simple server with any contexts mapping on any ports - target urls will always be correct.
Response res = client.targetRest("some").request().buildGet().invoke()
Assertions.assertEquals(200, res.getStatus())
Assertions.assertEquals("response text", res.readEntity(String))
Also, if you want to use other client, client object can simply provide required info:
client.getPort() // app port (8080)
client.getAdminPort() // app admin port (8081)
client.basePathMain() // main context path (http://localhost:8080/)
client.basePathAdmin() // admin context path (http://localhost:8081/)
client.basePathRest() // rest context path (http://localhost:8080/)
TestSupport¶
TestSupport
class simplifies usage of all test utilities: it is the only class you'll need
to remember - all other utilities could be created (or found) through it.
Methods inside it follow convention:
webApp
- complete application (DropwizardTestSupport
)coreApp
- guice-only part (GuiceyTestSupport
)
Methods:
runWebApp(Class, String, Callback?)
runCoreApp(Class, String, Callback?)
webApp(Class, String)
coreAoo(Class, String)
webClient(support)
getInjector(support)
getBean(support, Key/Class)
injectBeans(support, target)
run(support, Callback)
where support
is an instance of DropwizardTestSupport
(or GuiceyTestSupport
).
Simple run¶
If application must be just started and stopped (e.g. to test startup errors):
TestSupport.runWebApp(App.class, "path/to/test-config.yml");
or without configuration:
TestSupport.runWebApp(App.class, null);
More advanced version, using callback:
TestSupport.runWebApp(App.class, "path/to/test-config.yml", (injector) -> {
injector.getInstance(MyService.class).doSomething();
});
Here we get injector object inside callback and can call any guice service and perform any assertions while application runs. You can also use it to return a value:
String value = TestSupport.runWebApp(App.class, "path/to/test-config.yml", (injector) -> {
return injector.getInstance(MyService.class).computeValue()
});
All the same is available for lightweight guice-only testing:
TestSupport.runCoreApp(App.class, "path/to/test-config.yml", (injector) -> {
injector.getInstance(MyService.class).doSomething();
});
Advanced usage¶
For more advanced usage, you'll need to construct DropwizardTestSupport
or GuiceyTestSupport
objects first:
DropwizardTestSupport support = TestSupport.webApp(App.class, "path/to/test-config.yml");
or
GuiceyTestSupport support = TestSupport.coreApp(App.class, "path/to/test-config.yml");
Configuration path could be null:
DropwizardTestSupport support = TestSupport.webApp(App.class, null);
Note
This construction is suitable for the simplest cases, but you can always create
DropwizardTestSupport
object manually.
Utility call just hides easy to forget no-config instantiation:
new DropwizardTestSupport(App.class, (String) null);
Instead of manual lifecycle methods call you can use:
TestSupport.run(support, (injector) -> {
// do somthing while app started
})
Inside callback the following shortcuts could be used:
TestSupport.getInjector(support)
TestSupport.getBean(support, Key/Class)
TestSupport.injectBeans(support, target)
Complete example using junit:
public class RawTest {
static DropwizardTestSupport support;
@Inject MyService service;
@BeforeAll
public static void setup() {
support = TestSupport.coreApp(App.class, null);
// support = TestSupport.webApp(App.class, null);
// start app
support.before();
}
@BeforeEach
public void before() {
// inject services in test
TestSupport.injectBeans(support, this);
}
@AfterAll
public static void cleanup() {
if (support != null) {
support.after();
}
}
@Test
public void test() {
Assertions.assertEquals("10", service.computeValue());
}
}
Special needs¶
If you need to:
- Intercept application exit (e.g. startup crash)
- Validate system output (e.g. logs correctness)
- Change environment or system variables (with reset)
Then use system stubs library (low-level usage is described in project readme).