В настоящее время я ищу способы создания автоматических тестов для веб-службы JAX-RS (Java API для RESTful Web Services).
Мне в основном нужен способ отправить его определенным входам и проверить, что я получаю ожидаемые ответы. Я бы предпочел сделать это через JUnit, но я не уверен, как это можно достичь.
Какой подход вы используете для тестирования своих веб-сервисов?
Обновление: Как отметил энцик, развязка веб-службы из бизнес-логики позволяет мне unit test бизнес-логику. Тем не менее, я также хочу проверить правильные коды состояния HTTP и т.д.
Ответ 1
Jersey поставляется с отличным API-интерфейсом RESTful, который делает тесты модульных записей очень легкими. См. Блок-тесты в примерах, которые поставляются с Джерси. Мы используем этот подход для тестирования поддержки REST в Apache Camel, если вам интересно здесь >
Ответ 2
Вы можете опробовать REST Assured, что позволяет очень просто тестировать службы REST и проверять ответ на Java (используя JUnit или TestNG).
Ответ 3
Как сказал Джеймс; Существует встроенная тестовая среда для Джерси. Пример простого приветствия может быть таким:
pom.xml для интеграции maven. Когда вы запустите mvn test
. Рамки запускают контейнер гризли. Вы можете использовать причал или 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>
...
ExampleApp.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);
}
}
Вы можете проверить это пример приложения.
Ответ 4
Хотя его слишком поздно с даты публикации вопроса, подумал, что это может быть полезно для других, у кого есть аналогичный вопрос.
Джерси поставляется с тестовой платформой, называемой Jersey Test Framework, которая позволяет вам тестировать веб-службу RESTful, включая коды статуса ответа. Вы можете использовать его для запуска тестов на легких контейнерах, таких как Grizzly, HTTPServer и/или EmbeddedGlassFish. Кроме того, фрейм может использоваться для запуска ваших тестов на обычном веб-контейнере, таком как GlassFish или Tomcat.
Ответ 5
Вероятно, вы написали некоторый Java-код, который реализует вашу бизнес-логику, а затем вы создали конечную точку веб-служб для него.
Важная вещь, которую нужно сделать, - это самостоятельно протестировать свою бизнес-логику. Поскольку это чистый код Java, вы можете сделать это с помощью обычных тестов JUnit.
Теперь, поскольку часть веб-сервисов является лишь конечной точкой, вы должны убедиться, что созданная сантехника (заглушки и т.д.) синхронизируется с вашим java-кодом. вы можете это сделать, написав тесты JUnit, которые вызывают созданные Java-клиенты веб-сервисов. Это позволит вам узнать, когда вы меняете свои подписи java, не обновляя материал веб-сервисов.
Если ваша система веб-сервисов автоматически генерируется вашей системой сборки при каждой сборке, тогда может быть необязательно проверять конечные точки (при условии, что все это правильно сгенерировано). Зависит от вашего уровня паранойи.
Ответ 6
Я использую Apache HTTPClient (http://hc.apache.org/) для вызова Restful Services. Библиотека HTTP Client позволяет вам легко выполнять получение, публикацию или любую другую операцию, в которой вы нуждаетесь. Если ваша служба использует JAXB для привязки xml, вы можете создать JAXBContext для сериализации и десериализации входов и выходов из HTTP-запроса.
Ответ 7
Посмотрите генератор поколений алхимиков. Это может привести к реализации прокси для вашего веб-сервиса JAX-RS, используя jersey-клиент за сценой. Эффективно вы будете называть вас методами webservice как простые java-методы из ваших модульных тестов. Также обрабатывает HTTP-аутентификацию.
Не требуется генерация кода, если вам нужно просто запускать тесты, чтобы это было удобно.
Dislclaimer: Я являюсь автором этой библиотеки.
Ответ 8
Важная вещь, которую нужно сделать, это самостоятельно протестировать свою бизнес-логику
Я, конечно, не стал бы предполагать, что человек, который написал код JAX-RS и ищет интерфейс unit test, каким-то образом, по какой-то странной необъяснимой причине, не обращает внимания на то, что он или она может тестировать другие части программы, включая классы бизнес-логики. Нехорошо было заявить очевидное, и неоднократно подчеркивалось, что ответы также должны быть проверены.
И у Джерси, и у RESTEasy есть клиентские приложения, и в случае RESTEasy вы можете использовать те же аннотации (даже выставлять аннотированный интерфейс и использовать на клиентской и серверной стороне ваших тестов).
REST не то, что эта услуга может сделать для вас; REST, что вы можете сделать для этой услуги.
Ответ 9
Держите его простым. Посмотрите 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...
Ответ 10
Насколько я понимаю, основной целью автора этой проблемы является отключение уровня JAX RS от бизнес-интерфейса. И unit test только первый. Здесь мы должны решить две основные проблемы:
- Запустите в тестовом режиме веб-сервер/сервер приложений, добавьте компоненты JAX RS в
Это. И только они.
- Управление бизнес-сервисами внутри JAX RS
компонентов /REST.
Первая решена с Аркиллиан.
Второй вариант прекрасно описан в arquillican и mock
Вот пример кода, он может отличаться, если вы используете другой сервер приложений, но я надеюсь, что вы получите основную идею и преимущества.
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));
}
}
Несколько примечаний:
- Конфигурация JAX RS без web.xml используется здесь.
- Клиент JAX RS используется здесь (нет RESTEasy/Jersey, они предоставляют более удобный API)
- Когда начнется тест, начинает работать аркиллианский бегун. Здесь вы можете найти, как настроить тесты для Arquillian с необходимым сервером приложений.
- В зависимости от выбранного сервера приложений, URL-адрес
тест будет немного отличаться. Может использоваться другой порт. 8181 -
используемый Glassfish Embedded в моем примере.
Надеюсь, это поможет.