Request: Testing Example
Opened this issue · 6 comments
Do you guys use guice/dropwizard-guice while writing tests for your service/resource implementations? I'm curious to see an example in the example project.
👍
👍
My answer might be late, but nonetheless I'd like to share how I have used guice in my integration tests.
First of all I use the DropwizardAppRule
. I think that part is pretty straight forward.
My guice modules are MyModule
and MyTestModule
.
My application class looks like this:
public class MyApplication extends Application<MyConfiguration> {
private final Module module;
private GuiceBundle<MyConfiguration> guiceBundle;
public MyApplication() {
this(new MyModule());
}
public MyApplication(Module module) {
this.module = module;
}
// initialize [...]
protected GuiceBundle<MyConfiguration> getGuiceBundle() {
return guiceBundle;
}
}
My test application class looks like this:
public class MyTestApplication extends MyApplication {
public MyTestApplication() {
super(Modules.override(new MyModule()).with(new MyTestModule()));
}
public <T> T getInstance(Class<T> type) {
return getGuiceBundle().getInjector().getInstance(type);
}
}
In your tests you use the app rule as follows:
@ClassRule
public static final DropwizardAppRule<MyConfiguration> APP_RULE = new DropwizardAppRule<>(MyTestApplication.class, ResourceHelpers.resourceFilePath("configuration-example.json"));
This approach lets you override anything for testing. E.g. you can replace the database with a in memory implementation in the MyTestModule
. You can even get any instance created by guice with:
APP_RULE.getApplication().getInstance(SomeService.class);
I hope this helps. If you have any questions, please ask.
I use dropwizard 0.8.0.
If people are interested in putting this into the documentation, I can update the wiki/send a PR.
Personally I prefer to use Constructor Injections
so that my tests can use Mock objects or just new one up. That way I'm testing my code rather than testing guice
.
If you want to do Integration tests, it's exactly what @scho has mentioned. Also you can have a look at the test cases that we've added for 0.8.0 release:
- https://github.com/HubSpot/dropwizard-guice/blob/master/src/test/java/com/hubspot/dropwizard/guice/objects/TestApplication.java
- https://github.com/HubSpot/dropwizard-guice/blob/master/src/test/java/com/hubspot/dropwizard/guice/InjectedIntegrationTest.java
If you want to do Service and Resource tests and inject in your member variables, you can do this pretty standard guice
approach for junit:
public testMyGuice {
@Inject
Service testService;
@Before
public void setUpInjector() {
injector = Guice.createInjector(MyTestModule());
injector.injectMembers(this);
}
@Test
public myServiceShouldInject() {
assertThat(testService).isNotNull()
}
}
In this case, do you have the need to pass the test environment information (perhaps represented by TestConfiguration) to your MyTestModule() at all?
@patricioe it depends on if you need Environment
or TestConfiguration
(they are different things btw, TestConfiguration has nothing to do with Environment).
No, you don't need to pass it into MyTestModule(). If you need to inject in Environment
or TestConfiguration
, all you need to do is:
injector = Guice.createInjector(
new DropwizardEnvironmentModule<>(TestConfiguration.class),
MyTestModule()
)