Тестирование интеграции Джерси-Спринг с JerseyTest, Maven и TestNG - PullRequest
4 голосов
/ 16 ноября 2010

Я хочу проверить свои ресурсы на Джерси с помощью Jersey Test-Framework.

Я следовал приведенным здесь описаниям

для создания простого примера. Мой пример размещен в git-репозитории на http://github.com/rmetzler/Jersey-Test.

$ mvn jetty:run работает как положено, но я продолжаю получать исключения NullPointerException при выполнении $ mvn clean test.

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)
...

Могу поспорить, что допустил небольшую ошибку, которую не могу найти. Я бы показал свой источник другому разработчику, но, к сожалению, я работаю дома один. Так может кто-нибудь из вас может мне помочь?

UPDATE

Я создал проект Eclipse, запустив $ mvn eclipse:eclipse. Теперь, когда я запускаю тест как JUnit Test в Eclipse, он зеленый. При запуске как TestNG Test он не проходит. Так что я думаю, это как-то связано с тем, как TestNG выполняет тест.

Ответы [ 3 ]

5 голосов
/ 23 ноября 2010

Я сделал то же самое, за исключением того, что я использую подсказку, а не весну.Это моя реализация (извините, времени на очистку нет, вам придется самостоятельно извлекать интересные части).Обратите внимание, что я использовал класс jerseytest делегата, чтобы я мог наследовать некоторый код из моего базового тестового класса.Также вы должны сопоставить пре-и пост-методы junit с тестовыми.

Надеюсь, это немного поможет.


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();
    }
}
2 голосов
/ 13 мая 2014

Поскольку JerseyTest использует аннотацию @Before от Junit для инициализации приложения, и вам необходимо расширить 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.В противном случае эти тесты не пройдут быстро.

и, если вы хотите, чтобы он прочитал applicationContext-test.xml, отличный от файла по умолчанию, установите еще одно свойство для ResourceConfig:

config.setProperties(new HashMap<String, String>() {{
    put("contextConfigLocation", "applicationContext-test.xml");
}});

также, добавление некоторых функций в ClientConfig может оказаться полезным:

@Override
protected void configureClient(ClientConfig config) {
    config.register(LoggingFilter.class);
    config.register(MOXyJsonProvider.class);
    config.register(new EncodingFeature(GZipEncoder.class));
}

Все испытания на Джерси 2.6.

0 голосов
/ 14 сентября 2011

Простой пример использования Jersey + Spring + TestNG + Jetty здесь:

http://ameethpaatil.blogspot.com/2011/09/restful-webservice-jersey-spring-30x.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...