Вопрос

В настоящее время я ищу способы создания автоматизированных тестов для ДЖАКС-РС Веб-сервис на основе Java API для веб-служб RESTful.

По сути, мне нужен способ отправить ему определенные входные данные и убедиться, что я получаю ожидаемые ответы.Я бы предпочел сделать это через JUnit, но не знаю, как этого добиться.

Какой подход вы используете для тестирования своих веб-сервисов?

Обновлять: Как отметил Энцик, отделение веб-сервиса от бизнес-логики позволяет мне выполнить модульное тестирование бизнес-логики.Однако я также хочу проверить правильные коды состояния HTTP и т. д.

Это было полезно?

Решение

Джерси поставляется с отличным клиентским API RESTful, который упрощает написание модульных тестов.См. модульные тесты в примерах, поставляемых с Джерси.Мы используем этот подход для тестирования поддержки REST в Апач Верблюд, если вам интересно тестовые примеры здесь

Другие советы

Вы можете попробовать Будьте уверены что делает это очень просто тестировать службы REST и проверять ответ на Java (с использованием JUnit или TestNG).

Как сказал Джеймс;Есть встроенный тестовая среда для Джерси.Простой пример hello world может быть таким:

pom.xml для интеграции с maven.Когда ты бежишь mvn test.Фреймворки запускают контейнер Grizzly.Вы можете использовать jetty или tomcat, изменив зависимости.

...
<dependencies>
  <dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.16</version>
  </dependency>

  <dependency>
    <groupId>org.glassfish.jersey.test-framework</groupId>
    <artifactId>jersey-test-framework-core</artifactId>
    <version>2.16</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>2.16</version>
    <scope>test</scope>
  </dependency>
</dependencies>
...

ПримерApp.java

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/")
public class ExampleApp extends Application {

}

HelloWorld.java

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/")
public final class HelloWorld {

    @GET
    @Path("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHelloWorld() {

        return "Hello World!";
    }
}

HelloWorldTest.java

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.ws.rs.core.Application;
import static org.junit.Assert.assertEquals;

public class HelloWorldTest extends JerseyTest {

    @Test
    public void testSayHello() {

        final String hello = target("hello").request().get(String.class);

        assertEquals("Hello World!", hello);
    }

    @Override
    protected Application configure() {

        return new ResourceConfig(HelloWorld.class);
    }
}

Вы можете проверить этот образец заявления.

Хотя с момента публикации вопроса уже слишком поздно, я подумал, что это может быть полезно для других, у кого есть аналогичный вопрос.Джерси поставляется с тестовой средой под названием Платформа тестирования Джерси который позволяет вам протестировать вашу веб-службу RESTful, включая коды состояния ответа.Вы можете использовать его для запуска тестов на легких контейнерах, таких как Grizzly, HTTPServer и/или EmbeddedGlassFish.Кроме того, эту платформу можно использовать для запуска тестов в обычном веб-контейнере, таком как GlassFish или Tomcat.

Вероятно, вы написали какой-то Java-код, реализующий вашу бизнес-логику, а затем создали для него конечную точку веб-сервисов.

Важно самостоятельно протестировать свою бизнес-логику.Поскольку это чистый Java-код, вы можете сделать это с помощью обычных тестов JUnit.

Теперь, поскольку часть веб-сервисов является всего лишь конечной точкой, вы хотите убедиться, что сгенерированные элементы (заглушки и т. д.) синхронизированы с вашим Java-кодом.вы можете сделать это, написав тесты JUnit, которые вызывают сгенерированные Java-клиенты веб-службы.Это позволит вам узнать, когда вы измените свои подписи Java без обновления веб-сервисов.

Если ваши веб-сервисы автоматически создаются вашей системой сборки при каждой сборке, то, возможно, нет необходимости тестировать конечные точки (при условии, что все они сгенерированы правильно).Зависит от уровня вашей паранойи.

Я использую Apache HTTPClient (http://hc.apache.org/) позвонить в Restful Services.Библиотека HTTP-клиента позволяет вам легко выполнять получение, отправку или любую другую операцию, которая вам нужна.Если ваша служба использует JAXB для привязки XML, вы можете создать JAXBContext для сериализации и десериализации входных и выходных данных из HTTP-запроса.

Взгляни на Генератор клиента отдыха Alchemy.Это может создать реализацию прокси-сервера для вашего класса веб-сервиса JAX-RS, используя клиент Джерси за сценой.По сути, вы будете вызывать методы веб-сервиса как простые методы Java из своих модульных тестов.Также обрабатывает http-аутентификацию.

Если вам нужно просто запускать тесты, генерация кода не требуется, так что это удобно.

Отказ от ответственности:Я автор этой библиотеки.

Важно самостоятельно протестировать свою бизнес-логику.

Я, конечно, не стал бы предполагать, что человек, написавший код JAX-RS и желающий провести модульное тестирование интерфейса, каким-то образом, по какой-то причудливой, необъяснимой причине, не обращает внимания на мысль о том, что он или она может выполнять модульное тестирование других частей программы. включая классы бизнес-логики.Вряд ли полезно констатировать очевидное, и неоднократно отмечалось, что ответы также необходимо проверять.

И в Джерси, и в RESTEasy есть клиентские приложения, и в случае RESTEasy вы можете использовать одни и те же аннотации (даже исключить аннотированный интерфейс и использовать их на стороне клиента и сервера ваших тестов).

REST — это не то, что этот сервис может сделать для вас;REST, что вы можете сделать для этого сервиса.

Будь проще.Посмотри на https://github.com/valid4j/http-matchers который можно импортировать из Maven Central.

    <dependency>
        <groupId>org.valid4j</groupId>
        <artifactId>http-matchers</artifactId>
        <version>1.0</version>
    </dependency>

Пример использования:

// Statically import the library entry point:
import static org.valid4j.matchers.http.HttpResponseMatchers.*;

// Invoke your web service using plain JAX-RS. E.g:
Client client = ClientBuilder.newClient();
Response response = client.target("http://example.org/hello").request("text/plain").get();

// Verify the response
assertThat(response, hasStatus(Status.OK));
assertThat(response, hasHeader("Content-Encoding", equalTo("gzip")));
assertThat(response, hasEntity(equalTo("content")));
// etc...

Насколько я понимаю, основная цель автора этого выпуска — отделить уровень JAX RS от бизнес-уровня.И модульный тест только первый.Здесь нам предстоит решить две основные проблемы:

  1. Запустите в тестирование некоторых веб -сервера/приложений, поместите в него компоненты JAX RS.И только они.
  2. Их макет бизнес -услуги внутри компонентов JAX RS/REST.

Первый решается с помощью Arquillian.Второй прекрасно описан в аркилликан и макет

Вот пример кода, он может отличаться, если вы используете другой сервер приложений, но я надеюсь, что вы поняли основную идею и преимущества.

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import com.brandmaker.skinning.service.SomeBean;

/**
* Created by alexandr on 31.07.15.
*/
@Path("/entities")
public class RestBean
{
   @Inject
   SomeBean bean;

   @GET
   public String getEntiry()
   {
       return bean.methodToBeMoked();
   }
}

import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

import com.google.common.collect.Sets;

/**
*/
@ApplicationPath("res")
public class JAXRSConfiguration extends Application
{
   @Override
   public Set<Class<?>> getClasses()
   {
       return Sets.newHashSet(RestBean.class);
   }
}


public class SomeBean
{
   public String methodToBeMoked()
   {
       return "Original";
   }
}

import javax.enterprise.inject.Specializes;

import com.brandmaker.skinning.service.SomeBean;

/**
*/
@Specializes
public class SomeBeanMock extends SomeBean
{
   @Override
   public String methodToBeMoked()
   {
       return "Mocked";
   }
}

@RunWith(Arquillian.class)
public class RestBeanTest
{
   @Deployment
   public static WebArchive createDeployment() {
       WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
               .addClasses(JAXRSConfiguration.class, RestBean.class, SomeBean.class, SomeBeanMock.class)
               .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
       System.out.println(war.toString(true));
       return war;
   }

   @Test
   public void should_create_greeting() {
       Client client = ClientBuilder.newClient();
       WebTarget target = client.target("http://127.0.0.1:8181/test/res/entities");
       //Building the request i.e a GET request to the RESTful Webservice defined
       //by the URI in the WebTarget instance.
       Invocation invocation = target.request().buildGet();
       //Invoking the request to the RESTful API and capturing the Response.
       Response response = invocation.invoke();
       //As we know that this RESTful Webserivce returns the XML data which can be unmarshalled
       //into the instance of Books by using JAXB.
       Assert.assertEquals("Mocked", response.readEntity(String.class));
   }
}

Пара замечаний:

  1. Здесь используется конфигурация JAX RS без web.xml.
  2. Здесь используется JAX RS Client (нет RESTEasy/Jersey, они предоставляют более удобный API)
  3. Когда тест начинается, бегун Arquillian начинает работать. Здесь вы можете узнать, как настроить тесты для Arquillian с необходимым сервером приложений.
  4. В зависимости от выбранного сервера приложений, URL -адрес в тесте немного отличается.Можно использовать другой порт.8181 используется стеклянной рыбкой, встроенной в мой пример.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top