Перейти к основному содержимому

Введение в MockServer

· 5 мин. чтения

1. Обзор

MockServer — это инструмент для имитации/заглушки внешних API-интерфейсов HTTP.

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

Чтобы использовать MockServer в нашем приложении, нам нужно добавить две зависимости:

<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>3.10.8</version>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java</artifactId>
<version>3.10.8</version>
</dependency>

Последняя версия зависимостей доступна как mockserver-netty и mockserver-client.

3. Функциональность мок-сервера

Проще говоря, инструмент может:

  • генерировать и возвращать фиксированные ответы
  • перенаправить запрос на другой сервер
  • выполнять обратные вызовы
  • проверить запрос

4. Как запустить MockServer

Мы можем запустить сервер несколькими способами — давайте рассмотрим некоторые из этих способов.

4.1. Запуск через плагин Maven

Это запустит сервер на этапе process-test-class и остановится на этапе проверки :

<plugin>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-maven-plugin</artifactId>
<version>3.10.8</version>
<configuration>
<serverPort>1080</serverPort>
<proxyPort>1090</proxyPort>
<logLevel>DEBUG</logLevel>
<initializationClass>org.mockserver.maven.ExampleInitializationClass</initializationClass>
</configuration>
<executions>
<execution>
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>

4.2. Запуск через Java API

Мы можем использовать Java API startClientAndServer() для запуска сервера. Обычно мы запускаем сервер перед запуском всех тестов:

public class TestMockServer {

private ClientAndServer mockServer;

@BeforeClass
public void startServer() {
mockServer = startClientAndServer(1080);
}

@AfterClass
public void stopServer() {
mockServer.stop();
}

// ...
}

5. Имитация клиентов

MockServerClient API используется для предоставления возможности подключения к MockServer. Он моделирует запросы и соответствующие ответы от сервера.

Он поддерживает несколько операций:

5.1. Создание ожиданий с помощью фиктивных ответов

Ожидания — это механизм, с помощью которого мы имитируем запрос от клиента и результирующий ответ от MockServer.

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

Запросы могут быть сопоставлены с использованием:

  • путь — URL-адрес
  • строка запроса — параметры URL
  • заголовки — заголовки запроса
  • куки - куки на стороне клиента
  • body — тело запроса POST с XPATH, JSON, схемой JSON, регулярным выражением, точным соответствием параметрам обычного текста или тела

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

А ответное действие будет содержать:

  • коды состояния — действительные коды состояния HTTP, например, 200, 400 и т. д.
  • тело — это последовательность байтов, содержащая любой контент
  • заголовки — заголовки ответа с именем и одним или несколькими значениями
  • куки – ответные куки с именем и одним или несколькими значениями

Давайте посмотрим, как мы можем создать ожидание :

public class TestMockServer {
private void createExpectationForInvalidAuth() {
new MockServerClient("127.0.0.1", 1080)
.when(
request()
.withMethod("POST")
.withPath("/validate")
.withHeader("\"Content-type\", \"application/json\"")
.withBody(exact("{username: 'foo', password: 'bar'}")),
exactly(1))
.respond(
response()
.withStatusCode(401)
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400"))
.withBody("{ message: 'incorrect username and password combination' }")
.withDelay(TimeUnit.SECONDS,1)
);
}
// ...
}

Здесь мы заглушаем POST -запрос к серверу. И мы указали, сколько раз нам нужно сделать этот запрос, используя вызов точно (1) .

Получив этот запрос, мы имитировали ответ с такими полями, как код состояния, заголовки и тело ответа.

5.2. Пересылка запроса

Ожидание может быть настроено для пересылки запроса. Несколько параметров могут описать прямое действие:

  • хост — хост для пересылки, например, www.foreach.com
  • порт — порт, на который перенаправляется запрос, порт по умолчанию — 80.
  • схема — протокол для использования, например, HTTP или HTTPS

Давайте посмотрим на пример запроса на переадресацию:

private void createExpectationForForward(){
new MockServerClient("127.0.0.1", 1080)
.when(
request()
.withMethod("GET")
.withPath("/index.html"),
exactly(1))
.forward(
forward()
.withHost("www.mock-server.com")
.withPort(80)
.withScheme(HttpForward.Scheme.HTTP)
);
}

В этом случае мы смоделировали запрос, который попадет на MockServer ровно один раз, а затем будет перенаправлен на другой сервер. Внешний метод forward() определяет действие пересылки, а внутренний вызов метода forward() помогает создать URL-адрес и перенаправить запрос.

5.3. Выполнение обратного вызова

Сервер может быть настроен на выполнение обратного вызова при получении определенного запроса. Действие обратного вызова может определять класс обратного вызова, реализующий интерфейс org.mockserver.mock.action.ExpectationCallback . Он должен иметь конструктор по умолчанию и должен находиться в пути к классам.

Давайте посмотрим на пример ожидания с обратным вызовом:

private void createExpectationForCallBack() {
mockServer
.when(
request().withPath("/callback"))
.callback(
callback()
.withCallbackClass("com.foreach.mock.server.TestExpectationCallback")
);
}

Здесь внешний callback() указывает действие обратного вызова, а внутренний метод callback() указывает экземпляр класса метода обратного вызова.

В этом случае, когда MockServer получает запрос с /callback, будет выполнен метод дескриптора обратного вызова, реализованный в указанном классе:

public class TestExpectationCallback implements ExpectationCallback {

public HttpResponse handle(HttpRequest httpRequest) {
if (httpRequest.getPath().getValue().endsWith("/callback")) {
return httpResponse;
} else {
return notFoundResponse();
}
}

public static HttpResponse httpResponse = response()
.withStatusCode(200);
}

5.4. Проверка запросов

MockServerClient имеет возможность проверить, отправила ли тестируемая система запрос:

private void verifyPostRequest() {
new MockServerClient("localhost", 1080).verify(
request()
.withMethod("POST")
.withPath("/validate")
.withBody(exact("{username: 'foo', password: 'bar'}")),
VerificationTimes.exactly(1)
);
}

Здесь класс org.mockserver.verify.VerificationTimes используется для указания количества раз, когда фиктивный сервер должен соответствовать запросу.

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

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

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