Изучение рамок теста Джерси

Изучение рамок теста Джерси

1. обзор

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

Как мы уже видели в предыдущих статьях,Jersey is an open source framework for developing RESTful Web Services. Мы можем узнать больше о Джерси в нашей статье о создании API с Джерси и Spring -here.

2. Настройка приложения

Тестовая структура Jersey - это инструмент, помогающий нам проверить правильность реализации наших серверных компонентов. Как мы увидим позже,it provides a fast and fuss-free way for writing integration tests и очень хорошо справляется с взаимодействием с нашими HTTP API.

Likewise, it works almost out-of-the-box and it’s easy to integrate with our Maven-based projects. Фреймворк в основном основан на JUnit, хотя его можно использовать и с TestNG, что делает его пригодным для использования практически во всех средах.

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

2.1. Maven Зависимости

Прежде всего, давайте добавим базовую зависимость Jersey Test Framework к нашемуpom.xml:


    org.glassfish.jersey.test-framework
    jersey-test-framework-core
    2.27
    test

Как всегда, последнюю версию можно получить уMaven Central.

Практически почти во всех тестах на Джерси используется фабрика контейнеров для теста де-факто Grizzly, которую мы также должны добавить:


    org.glassfish.jersey.test-framework.providers
    jersey-test-framework-provider-grizzly2
    2.27
    test

Опять же, мы можем найти последнюю версию вMaven Central.

3. Начиная

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

Начнем с тестирования простого ресурсаGreetings на нашем сервере:

@Path("/greetings")
public class Greetings {

    @GET
    @Path("/hi")
    public String getHiGreeting() {
        return "hi";
    }
}

3.1. Настройка теста

Теперь давайте определим наш тестовый класс:

public class GreetingsResourceIntegrationTest extends JerseyTest {

    @Override
    protected Application configure() {
        return new ResourceConfig(Greetings.class);
    }
    //...
}

We can see in the above example that to develop a test using the Jersey Test Framework our test needs to subclass JerseyTest.

Затем мы переопределяем методconfigure, который возвращает настраиваемую конфигурацию ресурса для нашего теста и содержит только ресурсGreetings. Это, конечно, ресурс, который мы хотим протестировать.

3.2. Написание нашего первого теста

Давайте начнем с тестирования простого запроса GET из нашего приветственного API:

@Test
public void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() {
    Response response = target("/greetings/hi").request()
        .get();

    assertEquals("Http Response should be 200: ", Status.OK.getStatusCode(), response.getStatus());
    assertEquals("Http Content-Type should be: ", MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE));

    String content = response.readEntity(String.class);
    assertEquals("Content of ressponse is: ", "hi", content);
}

Обратите внимание, что у нас есть полный доступ к ответу HTTP -so we can do things like checking the status code to make sure the operation was actually successful, or work with the actual body of the response.

Давайте более подробно объясним, что мы делаем в приведенном выше примере:

  1. Отправьте HTTP-запрос GET на ‘/ greetings / hi '

  2. Проверьте код состояния HTTP и заголовки ответа типа содержимого

  3. Проверка содержимого ответа содержит строку «привет»

4. Тестирование GET для получения ресурсов

Итак, мы рассмотрели основные этапы создания тестов. Давайте протестируем простой Fruit API, который мы представили в отличномJersey MVC Support article.

4.1. Получить простой JSON

В приведенном ниже примере мы работаем с телом ответа как со стандартной строкой JSON:

@Test
public void givenFruitExists_whenSearching_thenResponseContainsFruit() {
    final String json = target("fruit/search/strawberry").request()
        .get(String.class);
    assertThat(json, containsString("{\"name\":\"strawberry\",\"weight\":20}"));
}

4.2. Получить сущность вместо JSON

Мы также можем сопоставить ответ непосредственно с классом сущности Resource - например:

   @Test
    public void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() {
        final Fruit entity = target("fruit/search/strawberry").request()
            .get(Fruit.class);

        assertEquals("Fruit name: ", "strawberry", entity.getName());
        assertEquals("Fruit weight: ", Integer.valueOf(20), entity.getWeight());
    }

На этот раз мы указываем тип Java, в который будет преобразована сущность ответа, в методеget - объектFruit.

5. Тестирование POST для создания ресурсов

Чтобы создать новый ресурс в нашем API - мы будем эффективно использовать POST-запросы. В следующем разделе мы увидим, как протестировать эту часть нашего API.

5.1. Опубликовать обычный JSON

Начнем с публикации простой строки JSON, чтобы протестировать создание нового фруктового ресурса:

@Test
public void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() {
    Response response = target("fruit/created").request()
        .post(Entity.json("{\"name\":\"strawberry\",\"weight\":20}"));

    assertEquals("Http Response should be 201 ", Status.CREATED.getStatusCode(), response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit saved : Fruit [name: strawberry colour: null]"));
}

В приведенном выше примере мы используем методpost, который принимает параметр объектаEntity. We use the convenient json method to create an entity from the corresponding JSON string.

5.2. Публикация объекта вместо JSON

As we’ve already seen with get requests we can also post a Resource entity class directly - например:

@Test
public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() {
    Fruit fruit = new Fruit("Blueberry", "purple");
    fruit.setWeight(1);

    Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE)
        .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE));

    assertEquals("Http Response should be 400 ", 400, response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater"));
}

На этот раз мы используем методentity для публикации нашей сущности Fruit, а также указываем тип носителя как JSON.

5.3. Отправка форм с использованием POST

В нашем последнем примере поста мы увидим, как проверить отправку формы с помощью пост-запроса:

@Test
public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() {
    Form form = new Form();
    form.param("name", "apple");
    form.param("colour", null);

    Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED)
        .post(Entity.form(form));

    assertEquals("Http Response should be 400 ", 400, response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null"));
 }

Точно так же мы используем классEntity, но на этот раз передаем форму, которая содержит ряд параметров, в наш почтовый запрос.

6. Тестирование других HTTP-глаголов

Иногда нам нужно проверить другие конечные точки HTTP, такие как PUT и DELETE. This is of course perfectly possible using the Jersey Test Framework.с

Давайте посмотрим на простой пример PUT:

@Test
public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() {
    Form form = new Form();
    form.param("serial", "2345-2345");

    Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED)
        .put(Entity.form(form));

    assertEquals("Http Response should be 400 ", 400, response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid"));
}

После того, как мы вызвали методrequest, мы можем вызвать любой HTTP-метод для текущего объекта запроса.

7. Дополнительные возможности

Платформа тестирования Джерси содержит ряд дополнительных свойств конфигурации, которые могут помочь при отладке и тестировании.

В следующем примере мы увидим, как программно включить функцию с заданным именем:

public class FruitResourceIntegrationTest extends JerseyTest {

    @Override
    protected Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);
        //...

Когда мы создаем и настраиваем наше тестируемое приложение на Джерси. Мы также можем включить дополнительные свойства. В этом случае мы включаем два свойства ведения журнала -LOG_TRAFFIC иDUMP_ENTITYwhich will provide useful additional logging and debug information during test runs.

8. Поддерживаемые контейнеры

Как мы уже упоминали, при написании тестов с помощью Jersey Test Framework по умолчанию используется контейнер Grizzly. However, a number of other containers are supported:с

  • Контейнер в памяти

  • HttpServer от Oracle JDK

  • Простой контейнер (org.simpleframework.http

  • Контейнер для причала (org.eclipse.jetty)

Дополнительные сведения о настройке этих контейнеров см. В документацииhere.

9. Заключение

Подводя итог, в этом уроке мы изучили среду тестирования Джерси. Сначала мы познакомились с настройкой среды тестирования Jersey, а затем увидели, как написать тест для очень простого API.

В следующем разделе мы увидели, как писать тесты для различных конечных точек GET и POST API. Наконец, мы рассмотрели некоторые дополнительные функции и контейнеры, которые поддерживает среда тестирования Jersey.

Как всегда, доступен полный исходный код статьиover on GitHub.