问题
There are REST web service based on Jersey 2.23.2 & Guice 3.0. To use Guice it is necessary to adjust the hk2-guice bridge (I'm using 2.5.0-b07). Everything works fine until I have tried to test the service using Jersey Test Framework. Can't configure hk2-guice bridge for tests.
My test:
public class SomeTest extends JerseyTestNg.ContainerPerClassTest {
@Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new GrizzlyWebTestContainerFactory();
}
@Override
protected Application configure() {
return super.configure(); // cant't configure
}
@Test
public void test() {
Assert.assertEquals(1, 1);
}
}
I can't configure test in SomeTest.configure()
just returning new JerseyConfiguration()
(see below) because JerseyConfiguration's constructor expected ServiceLocator's object.
Even if it were possible to return an object of class `JerseyConfiguration` - I'm not sure that my test would work because some filters and listener are defined in the web.xml file.
How to configure the test taking into account all filters, listener and hk2-guice bridge?
Web service details
Dependencies section from build.gradle:
def jerseyVersion = '2.23.2'
def hk2Version = '2.5.0-b07'
def giuceVersion = '3.0'
dependencies {
compile "javax.servlet:javax.servlet-api:3.1.0"
//jersey
compile "org.glassfish.jersey.core:jersey-server:${jerseyVersion}"
compile "org.glassfish.jersey.containers:jersey-container-servlet:${jerseyVersion}"
//hk2
compile "org.glassfish.hk2:guice-bridge:${hk2Version}"
//guice
compile "com.google.inject:guice:${giuceVersion}"
compile "com.google.inject.extensions:guice-servlet:${giuceVersion}"
}
File web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>REST API App</display-name>
<listener>
<listener-class>com.example.core.JerseyGuiceServletContextListener</listener-class>
</listener>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>jerseyFilter</filter-name>
<filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.core.JerseyConfiguration</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jerseyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Class JerseyGuiceServletContextListener:
public class JerseyGuiceServletContextListener extends GuiceServletContextListener {
static Injector injector;
@Override
protected Injector getInjector() {
injector = Guice.createInjector(new JerseyServletModuleConfig());
return injector;
}
}
Class JerseyServletModuleConfig:
class JerseyServletModuleConfig extends ServletModule {
@Override
protected void configureServlets() {
bind(HeyResource.class).in(Scopes.SINGLETON);
}
}
Class JerseyConfiguration:
package com.example.core;
import com.google.inject.Injector;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.jersey.server.ResourceConfig;
import org.jvnet.hk2.guice.bridge.api.GuiceBridge;
import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge;
import javax.inject.Inject;
import javax.servlet.ServletContext;
class JerseyConfiguration extends ResourceConfig {
@Inject
public JerseyConfiguration(ServiceLocator serviceLocator, ServletContext servletContext) {
packages("com.example.ws");
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(JerseyGuiceServletContextListener.injector);
}
}
回答1:
just overrode configureDeployment()
& modified configure()
methods in test
public class SomeTest extends JerseyTestNg.ContainerPerClassTest {
@Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new GrizzlyWebTestContainerFactory();
}
@Override
protected Application configure() {
return new ResourceConfig()
.packages("com.example.ws")
.register(GensonCustomResolver.class);
}
@Override
protected DeploymentContext configureDeployment() {
Application application = configure();
return ServletDeploymentContext.builder(application)
.addListener(JerseyGuiceServletContextListener.class)
.addFilter(GuiceFilter.class, "guiceFilter")
.addFilter(ServletContainer.class, "jerseyFilter", new HashMap<String, String>(){{
put("javax.ws.rs.Application", JerseyConfiguration.class.getCanonicalName());
}})
.build();
}
@Test
public void test() {
Assert.assertEquals(1, 1);
}
}
& add web.xml to test classpath.
来源:https://stackoverflow.com/questions/39225187/jersey-test-framework-hk2-guice-bridge