测试Jersey Spring与Jersey Test、Maven和TestNG的集成
我想用Jersey测试框架测试我的Jersey资源 我遵循这里提供的描述测试Jersey Spring与Jersey Test、Maven和TestNG的集成,spring,maven-2,jersey,testng,Spring,Maven 2,Jersey,Testng,我想用Jersey测试框架测试我的Jersey资源 我遵循这里提供的描述 创建一个简单的示例。我的示例在上作为git存储库托管 $mvn jetty:run按预期工作,但在运行$mvn clean test时,我不断收到NullPointerException java.lang.NullPointerException at com.sun.jersey.spi.container.ContainerResponse.mapException(ContainerResponse.jav
$mvn jetty:run
按预期工作,但在运行$mvn clean test
时,我不断收到NullPointerException
java.lang.NullPointerException
at com.sun.jersey.spi.container.ContainerResponse.mapException(ContainerResponse.java:429)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1295)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1239)
at com.sun.jersey.test.framework.impl.container.inmemory.TestResourceClientHandler.handle(TestResourceClientHandler.java:119)
at com.sun.jersey.api.client.Client.handle(Client.java:616)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:559)
at com.sun.jersey.api.client.WebResource.get(WebResource.java:182)
at example.jersey.spring.MyResourceTest.testMyResource(MyResourceTest.java:30)
...
我打赌我犯了一个我找不到的小错误。我会把我的源代码展示给另一个开发者,但不幸的是我一个人在家工作。也许你们中有人能帮我
更新
我通过运行
$mvnclipse:Eclipse
创建了一个Eclipse项目。现在,当我在Eclipse中作为JUnit测试运行测试时,它是绿色的。当作为TestNG Test运行时,它失败。所以我想这与TestNG如何执行测试有关。我做了同样的事情,只是我使用的是guice,而不是spring。这是我的实现(抱歉,没有时间清理,您必须自己提取有趣的部分)。请注意,我使用了一个委托jerseytest类,以便可以从基本测试类继承一些代码。还必须将junit的pre-and-post方法映射到testng方法
希望这有点帮助
package mypackage;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.net.URL;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.apache.commons.lang.UnhandledException;
import org.apache.xerces.dom.DOMInputImpl;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.FunctionObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.w3c.dom.Document;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.reflect.core.Reflection.staticMethod;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import com.sun.jersey.spi.container.WebApplication;
import com.sun.jersey.spi.container.WebApplicationFactory;
import com.sun.jersey.test.framework.AppDescriptor;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.LowLevelAppDescriptor;
import com.sun.jersey.test.framework.impl.container.inmemory.TestResourceClientHandler;
import com.sun.jersey.test.framework.spi.container.TestContainer;
import com.sun.jersey.test.framework.spi.container.TestContainerException;
import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
import com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory;
import mypackage.StaticConfig;
import mypackage.MediaTypes;
public abstract class JerseyIntegrationTestBase extends TransactionalIntegrationTestBase {
private static final Logger LOG = LoggerFactory.getLogger( JerseyIntegrationTestBase.class );
private static final class GuiceInMemoryTestContainerFactory extends InMemoryTestContainerFactory {
@Override
public TestContainer create( final URI baseUri, final AppDescriptor ad ) {
return new GuiceInMemoryTestContainer( baseUri, (LowLevelAppDescriptor) ad );
}
/**
* Kopie der Klasse im inmemory-Testcontainer von Jersey, leicht an Guice-Injection angepasst. The class defines methods for
* starting/stopping an in-memory test container, and for running tests on the container.
*/
private static class GuiceInMemoryTestContainer implements TestContainer {
final URI baseUri;
final ResourceConfig resourceConfig;
final WebApplication webApp;
/**
* Creates an instance of {@link GuiceInMemoryTestContainer}
*
* @param Base
* URI of the application
* @param An
* instance of {@link LowLevelAppDescriptor}
*/
private GuiceInMemoryTestContainer( final URI baseUri, final LowLevelAppDescriptor ad ) {
this.baseUri = UriBuilder.fromUri( baseUri ).build();
LOG.info( "Creating low level InMemory test container configured at the base URI " + this.baseUri );
resourceConfig = ad.getResourceConfig();
// Falls man mal in Tests die requests und responses sehen möchte:
// this.resourceConfig.getProperties().put( ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS,
// LoggingFilter.class.getName() );
// this.resourceConfig.getProperties().put( ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS,
// LoggingFilter.class.getName() );
resourceConfig.getProperties().putAll( StaticConfig.getJerseyParams() );
webApp = WebApplicationFactory.createWebApplication();
}
@Override
public Client getClient() {
ClientConfig clientConfig = null;
final Set providerSingletons = resourceConfig.getProviderSingletons();
if ( providerSingletons.size() > 0 ) {
clientConfig = new DefaultClientConfig();
for ( final Object providerSingleton : providerSingletons ) {
clientConfig.getSingletons().add( providerSingleton );
}
}
final Client client = clientConfig == null
? new Client( new TestResourceClientHandler( baseUri, webApp ) )
: new Client( new TestResourceClientHandler( baseUri, webApp ), clientConfig );
return client;
}
@Override
public URI getBaseUri() {
return baseUri;
}
@Override
public void start() {
if ( !webApp.isInitiated() ) {
LOG.info( "Starting low level InMemory test container" );
webApp.initiate( resourceConfig, new GuiceContainer( null ).new ServletGuiceComponentProviderFactory(
resourceConfig, IntegrationTestBase.getInjector() ) );
}
}
@Override
public void stop() {
if ( webApp.isInitiated() ) {
LOG.info( "Stopping low level InMemory test container" );
webApp.destroy();
}
}
}
}
private final JerseyTest _jerseyTest;
public JerseyIntegrationTestBase() {
// PackagesResourceConfig.getPackages macht genau das, was wir wollen, ist aber private, daher
// auf die harte Tour...
// FORMATTER: OFF
final String[] packages =
staticMethod( "getPackages" ).withReturnType( String[].class ).withParameterTypes( Map.class )
.in( PackagesResourceConfig.class ).invoke( StaticConfig.getJerseyParams() );
// FORMATTER: ON
_jerseyTest = new JerseyTest( new LowLevelAppDescriptor.Builder( packages ).build() ) {
@Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new GuiceInMemoryTestContainerFactory();
}
};
}
/**
* @return
* @see JerseyTest#client().
*/
protected Client client() {
return _jerseyTest.client();
}
@BeforeClass( alwaysRun = true )
public void setUp() throws Exception {
_jerseyTest.setUp();
}
@AfterClass( alwaysRun = true )
public void tearDown() throws Exception {
_jerseyTest.tearDown();
}
}
这里有一个使用Jersey+Spring+TestNG+Jetty的简单示例:
因为JerseyTest使用Junit中的@Before注释初始化应用程序,您必须扩展JerseyTest以启用testng支持,如下所示:
public class JerseyTestNG extends JerseyTest {
@Override
protected Application configure() {
ResourceConfig config = new ResourceConfig(YourService.class);
}
@BeforeClass
public void setUp() {
super.setUp();
}
@AfterClass
public void tearDown() {
super.tearDown();
}
}
@BeforeClass还将确保在使用surefire插件时,Jersey容器就绪后执行其中的所有测试。否则这些测试很快就会失败
如果要读取applicationContext-test.xml而不是默认值,请将另一个属性设置为ResourceConfig:
config.setProperties(new HashMap<String, String>() {{
put("contextConfigLocation", "applicationContext-test.xml");
}});
所有测试均在Jersey 2.6上进行。非常感谢您的回答。我忘了添加@BeforClass和@AfterClass注释^^
@Override
protected void configureClient(ClientConfig config) {
config.register(LoggingFilter.class);
config.register(MOXyJsonProvider.class);
config.register(new EncodingFeature(GZipEncoder.class));
}