Статьи

Accurest and Stub Runner 1.1.0.M3

В настоящее время в Spring Team мы готовим наши библиотеки к предстоящему финальному выпуску поезда Brixton. Это должно произойти в ближайшее время 🙂 До тех пор я трачу много времени после работы, свободное время на Accurest и Stub Runner .

Сегодняшний пост будет посвящен новым вещам, которые вы сможете получить в предстоящем выпуске Accurest 1.1.0 . Также вы можете воспользоваться большинством этих функций в версии 1.1.0.M3 .

Я просто быстро расскажу о функциях, но учтите, что вы можете прочитать о них подробнее в нашей документации .

Изменение имени

AccuREST запускался как библиотека, используемая для блокировки HTTP-вызовов. В следующем выпуске 1.1.0 вы также сможете отключить функцию обмена сообщениями. Вот почему имя меняется на Accurest. Это фантастическое имя, не так ли? 😉

Также, поскольку брендинг важен, теперь вместо вызова io.codearte.accurest.dsl.GroovyDsl вы можете вызвать io.codearte.accurest.dsl.Accurest 🙂

Поддержка обмена сообщениями

Это заняло у меня довольно много времени, но оно того стоило 🙂 Несколько бессонных ночей, и теперь вы можете получить прибыль от определения контрактов на обмен сообщениями. В HTTP у нас была сторона client / stub сторона server / test . Для обмена сообщениями мы добавили методы, которые помогут различить различия:

  • publisher сторона, для которой будут созданы тесты
  • consumer сторона, для которой конечные точки обмена сообщениями будут заглушены

контракт

Есть 3 варианта использования с точки зрения производителя сообщения.

  • что-то происходит в моем приложении, и я создаю выходное сообщение
  • кто-то отправляет сообщение в пункт назначения (очередь / тема), я прослушиваю это сообщение и создам выходное сообщение в другом месте
  • кто-то отправляет сообщение в пункт назначения (очередь / тема), я слушаю это сообщение и использую его без отправки сообщения

Здесь вы можете увидеть примеры контрактов для этих трех ситуаций (вы можете узнать больше об этом в документации ):

Выход срабатывает по методу

Выходное сообщение может быть запущено путем вызова метода (например, был запущен планировщик и отправлено сообщение)

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
def dsl = Accurest.make {
        // Human readable description
        description 'Some description'
        // Label by means of which the output message can be triggered
        label 'some_label'
        // input to the contract
        input {
                // the contract will be triggered by a method
                triggeredBy('bookReturnedTriggered()')
        }
        // output message of the contract
        outputMessage {
                // destination to which the output message will be sent
                sentTo('output')
                // the body of the output message
                body('''{ "bookName" : "foo" }''')
                // the headers of the output message
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}

Выход срабатывает по сообщению

Выходное сообщение может быть запущено при получении сообщения.

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
def dsl = GroovyDsl.make {
        description 'Some Description'
        label 'some_label'
        // input is a message
        input {
                // the message was received from this destination
                messageFrom('input')
                // has the following body
                messageBody([
                        bookName: 'foo'
                ])
                // and the following headers
                messageHeaders {
                        header('sample', 'header')
                }
        }
        outputMessage {
                sentTo('output')
                body([
                        bookName: 'foo'
                ])
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}

Нет выхода, только вход

Там может быть только вход без какого-либо вывода

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
def dsl = GroovyDsl.make {
        description 'Some Description'
        label 'some_label'
        // input is a message
        input {
                // the message was received from this destination
                messageFrom('input')
                // has the following body
                messageBody([
                        bookName: 'foo'
                ])
                // and the following headers
                messageHeaders {
                        header('sample', 'header')
                }
        }
}

Сторона производителя

Здесь вы можете увидеть пример сгенерированного JUnit теста для производителя для сценария ввода / вывода:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
// given:
 AccurestMessage inputMessage = accurestMessaging.create(
  "{\\"bookName\\":\\"foo\\"}"
, headers()
  .header("sample", "header"));
 
// when:
 accurestMessaging.send(inputMessage, "input");
 
// then:
 AccurestMessage response = accurestMessaging.receiveMessage("output");
 assertThat(response).isNotNull();
 assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo");
// and:
 DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload()));
 assertThatJson(parsedJson).field("bookName").isEqualTo("foo");

Мы отправляем сообщение в пункт назначения с именем input . Затем мы проверяем, есть ли сообщение в месте назначения output . Если это так, мы проверяем, имеет ли это сообщение правильные заголовки и тело.

Потребительская сторона

Достаточно указать зависимость от соответствующего модуля Stub Runner (для получения дополнительной информации обратитесь к следующему разделу) и указать, какие заглушки следует загружать. Да это все! Stub Runner загрузит заглушки и подготовит заглушки .

Иногда вам нужно как-то вызвать сообщение в ваших тестах. Вот почему мы предоставили интерфейс StubTrigger который вы можете ввести! Если вы уже знакомы с Stub Runner Spring, вы можете использовать бин StubFinder чтобы найти URL своей зависимости. Теперь StubFinder также расширяет интерфейс StubTrigger поэтому вам не нужно вводить какие-либо дополнительные bean-компоненты в ваши тесты.

Есть несколько способов, которыми вы можете вызвать сообщение:

Триггер по метке

1
stubFinder.trigger('return_book_1')

Запуск по группам и идентификаторам артефактов

1
stubFinder.trigger('io.codearte.accurest.stubs:camelService', 'return_book_1')

Запуск по идентификатору артефакта

1
stubFinder.trigger('camelService', 'return_book_1')

Запустить все сообщения

1
stubFinder.trigger()

Интеграции

Мы предоставляем следующие встроенные функции:

  • Весенняя интеграция
  • Весенний облачный поток
  • Apache Camel

Также мы предоставляем все строительные блоки для обеспечения индивидуальной интеграции.

Просто предоставляя правильную зависимость

1
2
3
4
5
6
// for Apache Camel
testCompile "io.codearte.accurest:accurest-messaging-camel:${accurestVersion}"
// for Spring Integration
testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}"
// for Spring Cloud Stream
testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}"

Ваши сгенерированные тесты должны просто работать.

Ботинок бегуна окурка

Я добавил новый модуль Stub Runner, который работает на Spring Boot. Предполагая, что вы используете Spring Cloud Stream, вы можете создать проект, который имеет 2 зависимости:

1
2
compile "io.codearte.accurest:stub-runner-boot:${accurestVersion}"
compile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}"

Теперь, если вы передадите правильную конфигурацию Stub Runner Spring, например:

1
stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService

У вас будет запущенное приложение, которое предоставляет конечные точки HTTP

  • инициировать сообщения
  • проверьте URL-адреса зарегистрированных заглушек WireMock

Accurest Maven Плагин

Мариуш Смикула проделал фантастическую работу, добавив плагин Accurest Maven . Теперь вы можете добавить Accurest в ваш проект, который работает с Maven. Но это еще не все, поскольку плагин Maven позволяет запускать заглушки Accurest с помощью команды accurest:run !

Читайте документы, чтобы узнать больше!

Изменения заглушки

обмен сообщениями

В качестве функции обмена сообщениями я добавил несколько модулей обмена сообщениями. Вы можете прочитать больше о модулях сообщений Stub Runner здесь

Исправлены порты и версии заглушек

Еще одна особенность, которая отсутствовала и является действительно ценной, заключается в том, что теперь вы можете явно сказать, что хотите, чтобы конкретная зависимость запускалась на данном порту. Эта функция доступна с версии 1.0.7 но идентификатор заглушки был изменен в 1.1.0.M4 так что будьте 1.1.0.M4 😉

Идентификаторы изменились, потому что теперь вы можете указать желаемую версию заглушки, которую хотите загрузить.

Через свойства

Теперь вы можете указать идентификатор заглушки:

1
groupId:artifactId:version:classifier:port

где версия, классификатор и порт не являются обязательными.

  • Если вы не предоставите порт, то будет выбран случайный
  • Если вы не предоставите классификатор, то будет выбран класс по умолчанию.
  • Если вы не предоставите версию, то + будет пройден, и будет загружена самая последняя версия.

Где порт означает порт сервера WireMock.

Так что, если вы предоставите свою зависимость следующим образом:

1
stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs:9090,io.codearte.accurest.stubs:anotherService:+:9095

Это сделает Stub Runner:

  • загрузите заглушку с groupId: io.codearte.accurest.stubs , artifactId: streamService , версия: 0.0.1-SNAPSHOT , классификатор: stubs и зарегистрируйте ее на порту 9090
  • загрузите заглушку с groupId: io.codearte.accurest.stubs , artifactId: anotherService , последняя версия, классификатор по умолчанию ( stubs ) и зарегистрируйте его на порту 9095

Через свободный API

При использовании AccurestRule вы можете добавить заглушку для загрузки, а затем передать порт для последней загруженной заглушки.

1
2
3
4
5
@ClassRule public static AccurestRule rule = new AccurestRule()
                .repoRoot(repoRoot())
                .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
                .withPort(12345)
                .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:12346");

Вы можете видеть, что для этого примера допустим следующий тест:

1
2
then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL());
then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL());

Технические изменения

Помимо функций мы провели технический рефакторинг.

Виноград -> Эфир

Я перенес механизм, используемый для загрузки зависимостей из Groovy Grape в Aether. У нас было много проблем с Grape, и Aether работает очень хорошо. Это обратное несовместимое изменение, поэтому, если у вас есть какая-то настраиваемая конфигурация Grape, вам придется перенести ее на Aether.

Зависимости исправлены

У нас были некоторые проблемы с явными и транзитивными зависимостями, которые были исправлены. Банки Accurest должны быть меньше.

Резюме

  • Много работы было сделано вокруг Accurest и CDC
  • Довольно скоро мы выпустим версию 1.1.0
  • Вы можете использовать заглушки ваших зависимостей, которые общаются через обмен сообщениями
  • Вы можете использовать фиксированные порты и версии для ваших зависимостей
  • Если вам нравится проект, начинайте его на Github 🙂 Это даст нам дополнительный заряд энергии, чтобы тратить на кодирование вместо сна;)

связи

Ссылка: Accurest и Stub Runner 1.1.0.M3 от нашего партнера по JCG Марцина Грэйсчака в блоге для кодирования блогов наркоманов .