I've been using Jersey 1.X with Google Guice for dependency injection. Switching to Jersey 2.X seems to mean you need to use HK2 for dependency injection instead, I'm struggling to find a few things that I had in Guice.
In Jersey 1.X with Guice, I would have something like this for the application:
public class GuiceServletTestConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModule(){
@Override
protected void configureServlets(){
bind(MyResource.class);
serve("/*").with(GuiceContainer.class);
bind(MyDAO.class).to(MyDAOSQL.class)
}
});
}
}
And something like this for tests:
public class GuiceServletTestConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModule(){
@Override
protected void configureServlets(){
bind(MyResource.class);
serve("/*").with(GuiceContainer.class);
}
@Provides
MyDAO provideMockMyDAO(){
MyDAO dao = mock(MyDAO.class);
return dao;
}
});
}
}
Any my resrouce would look like this:
@Path("myresource")
public class MyResource {
private MyDAO myDAO;
@Inject
protected void setMyDAO(MyDAO myDAO) {
this.myDAO = myDAO;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response get() {
// Do something with myDAO
// Return response
}
}
That was I can define mocks for my tests and everything is good.
With Jersey 2.X however, I cannot find any equivalent for the @Provides annotation. MyResource is effectively the same. For dependency injection for the real application, I have:
public class Application extends ResourceConfig {
public Application() {
packages("com.my.package.resources");
register(new AbstractBinder() {
@Override
protected void configure() {
bind(MyDAOSQL.class).to(MyDAO.class);
}
});
}
}
But I don't know how to provide mocks for tests. Anyone knoe how?
OK, so I figured out a way that works for me. One thing that threw me off was the swapping of the bind().to()
from Guice to HK2. In Guice, you write:
bind(Abstract.class).to(Concrete.class)
Where as in HK2, you write:
bind(Concrete.class).to(Abstract.class)
The way to get the provides behaviour can be achieved with the following code:
public class MyResourceIT extends JerseyTest {
@Override
protected Application configure() {
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.register(MyResource.class);
resourceConfig.register(new AbstractBinder() {
@Override
protected void configure() {
bind(provideMyDaoMock()).to(MyDao.class);
}
private MyDao provideMyDaoMock() {
MyDao myDaoMock = mock(MyDao.class);
return myDaoMock;
}
});
return resourceConfig;
}
}