1. Обзор
Эта статья будет посвящена тестированию службы RESTful с несколькими типами / представлениями мультимедиа. Это десятая из серии статей о настройке защищенной веб-службы RESTful с использованием Spring и Spring Security с настройкой на основе Java.
Серия «Отдых с весной»:
- Часть 1. Начальная загрузка веб-приложения с помощью Spring 3.1 и конфигурации на основе Java
- P art 2 — Создание веб-службы RESTful с помощью Spring 3.1 и конфигурации на основе Java
- P art 3 — Защита веб-службы RESTful с помощью Spring Security 3.1
- Часть 4. Обнаружение веб-службы RESTful
- Часть 5. Обнаружение службы REST с помощью Spring
- Часть 6. Базовая и дайджест-проверка подлинности для службы RESTful с Spring Security 3.1
- Часть 7. REST Pagination весной
- Часть 8. Аутентификация на RESTful-сервисе с помощью Spring Security
- Часть 9 — ETAG для отдыха с пружиной
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 .