Статьи

Тестирование REST с несколькими типами MIME

1. Обзор

Эта статья будет посвящена тестированию службы RESTful с несколькими типами / представлениями мультимедиа. Это десятая из серии статей о настройке защищенной веб-службы RESTful с использованием Spring и Spring Security с настройкой на основе Java.

Серия «Отдых с весной»:

2. Цели

Любой сервис RESTful должен предоставлять свои Ресурсы в виде представлений, используя какой-либо тип носителя, а во многих случаях более одного. Клиент установит заголовок Accept, чтобы выбрать тип представления, который он запрашивает у службы. Поскольку у ресурса может быть несколько представлений, сервер должен будет реализовать механизм, отвечающий за выбор правильного представления, также известный как согласование содержимого. Таким образом, если клиент запрашивает application / xml , он должен получить XML-представление ресурса, а если он запрашивает application / json , то он должен получить JSON.

В этой статье объясняется, как писать интеграционные тесты, способные переключаться между несколькими типами представлений, которые поддерживает служба RESTful. Цель состоит в том, чтобы иметь возможность выполнять точно такой же тест, используя те же идентификаторы URI службы, просто запрашивая другой тип носителя.

3. Инфраструктура тестирования

Мы начнем с определения простого интерфейса для маршаллера — это будет основная абстракция, которая позволит тесту переключаться между различными типами медиа:

1
2
3
4
public interface IMarshaller {
    ...
    String getMime();
}

Затем нам нужен способ инициализации правильного маршаллера на основе некоторой формы внешней конфигурации. Для этого механизма мы будем использовать Spring FactoryBean для инициализации маршаллера и простое свойство, чтобы определить, какой маршаллер использовать:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Component
@Profile('test')
public class TestMarshallerFactory implements FactoryBean<IMarshaller> {
    @Autowired
    private Environment env;
    public IMarshaller getObject() {
        String testMime = env.getProperty('test.mime');
        if (testMime != null) {
            switch (testMime) {
            case 'json':
                return new JacksonMarshaller();
            case 'xml':
                return new XStreamMarshaller();
            default:
                throw new IllegalStateException();
            }
        }
        return new JacksonMarshaller();
    }
    public Class<IMarshaller> getObjectType() {
        return IMarshaller.class;
    }
    public boolean isSingleton() {
        return true;
    }
}

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

  • во-первых, здесь используется новая абстракция среды, представленная в Spring 3.1 — подробнее об этом читайте в статье Properties with Spring
  • свойство test.mime извлекается из среды и используется для определения того, какой маршаллер следует создать — здесь работает какой-то Java 7-й синтаксис String
  • далее маршаллер по умолчанию , если свойство вообще не определено, будет маршаллером Джексона для поддержки JSON
  • наконец — этот BeanFactory активен только в тестовом сценарии, так как используется новая поддержка @Profile , также представленная в Spring 3.1

Вот и все — механизм может переключаться между маршалерами в зависимости от значения свойства test.mime .

4. JSON и XML Marshallers

Далее нам понадобится реальная реализация marhsaller — по одной для каждого поддерживаемого типа носителя.

Для JSON мы будем использовать Джексона в качестве базовой библиотеки:

01
02
03
04
05
06
07
08
09
10
11
12
public class JacksonMarshaller implements IMarshaller {
    private ObjectMapper objectMapper;
    public JacksonMarshaller() {
        super();
        objectMapper = new ObjectMapper();
    }
    ...
    @Override
    public String getMime() {
        return MediaType.APPLICATION_JSON.toString();
    }
}

Для поддержки XML маршаллер использует XStream :

01
02
03
04
05
06
07
08
09
10
11
public class XStreamMarshaller implements IMarshaller {
    private XStream xstream;
    public XStreamMarshaller() {
        super();
        xstream = new XStream();
    }
    ...
    public String getMime() {
        return MediaType.APPLICATION_XML.toString();
    }
}

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

5. Использование сервиса с использованием JSON и XML

На этом этапе мы сможем выполнить полное тестирование интеграции с развернутым сервисом RESTful. Использовать маршаллера просто — IMarshaller просто вводится непосредственно в тест:

1
2
3
4
5
6
7
@ActiveProfiles({ 'test' })
public abstract class SomeRestLiveTest {
    @Autowired
    private IMarshaller marshaller;
    // tests
    ...
}

Точный маршаллер, который будет введен Spring, будет, конечно, определяться значением свойства test.mime ; это можно выбрать из файла свойств или просто установить в тестовой среде вручную. Однако если значение для этого свойства не указано, TestMarshallerFactory просто использует маршаллер по умолчанию — маршаллер JSON.

6. Мавен и Дженкинс

Если Maven настроен для запуска интеграционных тестов с уже развернутой службой RESTful, то его можно запустить следующим образом:

1
mvn test -Dtest.mime=xml

Или, если эта сборка использует фазу тестирования интеграции жизненного цикла Maven:

1
mvn integration-test -Dtest.mime=xml

Для получения дополнительной информации о том, как использовать эти этапы и как настроить сборку Maven, чтобы она связывала развертывание приложения с целью предварительного тестирования интеграции , запустите интеграционные тесты в цели тестирования интеграции и затем завершите работу. разверните развернутую службу после тестирования интеграции , см. статью « Тестирование интеграции с Maven» .

В Jenkins задание должно быть настроено с помощью:

1
This build is parameterized

И добавлен параметр String : test.mime = xml .

Обычная конфигурация Jenkins — это задания, выполняющие один и тот же набор интеграционных тестов для развернутой службы — один с XML, а другой с JSON-представлениями.

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

В этой статье показано, как правильно протестировать REST API. Большинство API публикуют свои ресурсы в нескольких представлениях, поэтому тестирование всех этих представлений жизненно важно, и использование точно таких же тестов для этого просто здорово.

Для полной реализации этого механизма в реальных интеграционных тестах, проверяющих как XML, так и JSON-представления всех ресурсов, ознакомьтесь с проектом github .

Ссылка: Тестирование REST с несколькими типами MIME от нашего партнера JCG Юджина Параскива в блоге baeldung .