Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
测试Jersey Spring与Jersey Test、Maven和TestNG的集成_Spring_Maven 2_Jersey_Testng - Fatal编程技术网

测试Jersey Spring与Jersey Test、Maven和TestNG的集成

测试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

我想用Jersey测试框架测试我的Jersey资源

我遵循这里提供的描述

创建一个简单的示例。我的示例在上作为git存储库托管

$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));
}