В настоящее время я ищу способы создания автоматических тестов для веб-службы на основе JAX-RS (Java API для RESTful Web Services).
Мне в основном нужен способ отправить ему определенные данные и убедиться, что я получаю ожидаемые ответы. Я бы предпочел сделать это через JUnit, но я не уверен, как этого можно достичь.
Какой подход вы используете для тестирования своих веб-сервисов?
Обновление: как отметил энцик, отделение веб-службы от бизнес-логики позволяет мне проводить модульное тестирование бизнес-логики. Однако я также хочу проверить правильность кодов состояния HTTP и т. Д.
Ответы:
В Jersey есть отличный клиентский API RESTful, который упрощает написание модульных тестов. См. Модульные тесты в примерах, поставляемых с Jersey. Мы используем этот подход для тестирования поддержки REST в Apache Camel , если вам интересно, тестовые примеры здесь
источник
Вы можете попробовать , будьте уверены , что делает его очень просто к услугам тестирования REST и проверки ответа на Java ( с использованием JUnit или TestNG).
источник
Как сказал Джеймс; Для Джерси есть встроенная тестовая среда . Простой пример hello world может быть таким:
pom.xml для интеграции с maven. Когда ты бежишь
mvn test
. Каркасы запускают контейнер гризли. Вы можете использовать причал или кот, изменяя зависимости.... <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); } }
Вы можете проверить этот образец приложения.
источник
jersey-hk2
в качестве зависимости, потому что я получалjava.lang.IllegalStateException: InjectionManagerFactory
ошибку «не найдено» (см. Этот вопрос ). В остальном этот пример работает хорошо.Вы, вероятно, написали какой-то java-код, который реализует вашу бизнес-логику, а затем сгенерировали для него конечную точку веб-служб.
Важно самостоятельно проверить свою бизнес-логику. Поскольку это чистый java-код, вы можете делать это с помощью обычных тестов JUnit.
Теперь, поскольку часть веб-служб - это всего лишь конечная точка, вы хотите убедиться, что сгенерированная сантехника (заглушки и т. Д.) Синхронизирована с вашим java-кодом. вы можете сделать это, написав тесты JUnit, которые вызывают сгенерированные java-клиенты веб-службы. Это даст вам знать, когда вы измените свои подписи Java без обновления материала веб-сервисов.
Если сантехника ваших веб-служб автоматически генерируется вашей системой сборки при каждой сборке, то, возможно, нет необходимости тестировать конечные точки (при условии, что все они сгенерированы правильно). Зависит от вашего уровня паранойи.
источник
Хотя уже слишком поздно с момента публикации вопроса, подумал, что это может быть полезно для других, у которых есть аналогичный вопрос. Jersey поставляется с тестовой платформой, называемой Jersey Test Framework, которая позволяет тестировать веб-службу RESTful, включая коды состояния ответа. Вы можете использовать его для запуска тестов на легких контейнерах, таких как Grizzly, HTTPServer и / или EmbeddedGlassFish. Кроме того, фреймворк можно использовать для запуска ваших тестов в обычном веб-контейнере, таком как GlassFish или Tomcat.
источник
Я использую HTTPClient Apache (http://hc.apache.org/) для вызова Restful Services. Клиентская библиотека HTTP позволяет легко выполнять получение, публикацию или любую другую операцию, которая вам нужна. Если ваша служба использует JAXB для привязки xml, вы можете создать JAXBContext для сериализации и десериализации входных и выходных данных из HTTP-запроса.
источник
Взгляните на генератор клиентов отдыха Alchemy . Это может сгенерировать реализацию прокси для вашего класса веб-службы JAX-RS с использованием клиента jersey за сценой. Фактически вы будете называть свои методы веб-сервиса простыми java-методами из ваших модульных тестов. Также обрабатывает HTTP-аутентификацию.
Генерация кода не требуется, если вам нужно просто запускать тесты, поэтому это удобно.
Отказ от ответственности: я являюсь автором этой библиотеки.
источник
Будь проще. Взгляните на 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 и хочет провести модульное тестирование интерфейса, каким-то образом, по какой-то странной, необъяснимой причине, не обращает внимания на то, что он или она может выполнять модульное тестирование других частей программы, включая классы бизнес-логики. Вряд ли полезно констатировать очевидное, и неоднократно подчеркивалось, что ответы тоже нужно проверять.
И у Jersey, и у RESTEasy есть клиентские приложения, и в случае RESTEasy вы можете использовать одни и те же аннотации (даже исключить аннотированный интерфейс и использовать на клиентской и серверной стороне ваших тестов).
REST - это не то, что эта служба может для вас сделать; ОТДЫХАЙТЕ, что вы можете сделать для этой службы.
источник
Насколько я понимаю, основная цель автора этого выпуска - отделить уровень JAX RS от бизнес-уровня. И юнит-тест только первый. Здесь мы должны решить две основные проблемы:
Первый решается с помощью Аркиллиана. Второй прекрасно описан аркилликанским языком и имитирует
Вот пример кода, он может отличаться, если вы используете другой сервер приложений, но я надеюсь, что вы поймете основную идею и преимущества.
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)); } }
Пара замечаний:
Надеюсь, это поможет.
источник