Введение в MockServer
MockServer — это инструмент для имитации/заглушки внешних API-интерфейсов HTTP.
2. Зависимости Maven
Чтобы использовать MockServer в нашем приложении, нам нужно добавить две зависимости:
dependency> groupId>org.mock-servergroupId> artifactId>mockserver-nettyartifactId> version>3.10.8version> dependency> dependency> groupId>org.mock-servergroupId> artifactId>mockserver-client-javaartifactId> version>3.10.8version> dependency>
Последняя версия зависимостей доступна как mockserver-netty и mockserver-client.
3. Функциональность мок-сервера
Проще говоря, инструмент может:
- генерировать и возвращать фиксированные ответы
- перенаправить запрос на другой сервер
- выполнять обратные вызовы
- проверить запрос
4. Как запустить MockServer
Мы можем запустить сервер несколькими способами — давайте рассмотрим некоторые из этих способов.
4.1. Запуск через плагин Maven
Это запустит сервер на этапе process-test-class и остановится на этапе проверки :
plugin> groupId>org.mock-servergroupId> artifactId>mockserver-maven-pluginartifactId> version>3.10.8version> configuration> serverPort>1080serverPort> proxyPort>1090proxyPort> logLevel>DEBUGlogLevel> initializationClass>org.mockserver.maven.ExampleInitializationClassinitializationClass> configuration> executions> execution> id>process-test-classesid> phase>process-test-classesphase> goals> goal>startgoal> goals> execution> execution> id>verifyid> phase>verifyphase> goals> goal>stopgoal> 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("")), 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("")), VerificationTimes.exactly(1) ); >
Здесь класс org.mockserver.verify.VerificationTimes используется для указания количества раз, когда фиктивный сервер должен соответствовать запросу.
6. Заключение
В этой быстрой статье мы рассмотрели различные функции MockServer. Мы также изучили различные предоставляемые API и то, как их можно использовать для тестирования сложных систем.
Как всегда, полный код для этой статьи доступен на GitHub.
Mockito
Mockito — фреймворк для тестирования приложений, который позволяет легко и быстро подменять реальные объекты программы «пустышками». Такие фиктивные объекты часто называют «моками» (Mock — подражать).
Зачем используется Mockito
Инструмент упрощает разработку юнит-тестов для классов с внешними зависимостями. Фиктивная реализация интерфейса, статического метода или класса, которую производит Mockito, позволяет определить вывод конкретных вызовов методов: фиктивные классы записывают взаимодействие с системой, а тесты могут его проверить и подтвердить.

Профессия / 16 месяцев
Тестировщик-автоматизатор
Лучший выбор для быстрого старта в IT

Подключение Mockito
Обычно библиотека подключается к системе сборки приложений, которой пользуется разработчик, — Maven или Gradle. В случае с Gradle установка Mockito выглядит так:
При использовании Maven библиотека добавляется в зависимости таким образом:
В случае совместного использования JUnit 5 и Mockito в Maven также добавляется следующая зависимость:

Кроме систем сборки, библиотеку можно подключить к любой интегрированной среде разработки. Все популярные IDE — Eclipse, Android Studio, Visual Studio Code, IntelliJ IDEA — поддерживают как Mockito, так и Maven, JUnit и Gradle.

Станьте тестировщиком – это лучший выбор для быстрого старта в IT
Базовые понятия тестирования
Юнит-тесты позволяют проверять поведение определенных классов или методов в отрыве от их зависимостей. Так как тестируют самые маленькие «элементы» кода, не нужно использовать настоящие реализации зависимостей. Более того, чтобы протестировать различные модели поведения, часто требуется применять немного разные реализации этих зависимостей. Традиционный подход к тестированию — создание «заглушек», конкретных реализаций интерфейса, подходящих для данного сценария. Такие реализации имеют жестко закодированную логику. Заглушка — разновидность тестового двойника (как и фиктивные объекты, макеты, шпионы и так далее). В Mockito чаще всего используются два типа тестовых двойников — макеты (mocks) и шпионы (spies).
Макеты (моки)
Такое тестирование называют мокингом. Создаются объекты-имитаторы, которые реализуют поведение реальной подсистемы. Моки используются как замена зависимостей.
С помощью Mockito разработчик создает имитатор — мок, указывает библиотеке, что делать при вызове определенных методов, а затем использует экземпляр имитатора в своем тесте вместо реального объекта. По умолчанию Mockito предоставляет реализацию для каждого метода mock. После тестирования можно запросить mock, чтобы узнать, какие конкретные методы были вызваны, или проверить побочные эффекты в виде изменения состояния.
Шпионы
Шпион — второй тестовый двойник, который создает Mockito. Для этого требуется экземпляр объекта, за которым можно наблюдать — шпионить. По умолчанию шпион делегирует все вызовы методов реальному объекту и записывает, какой метод был вызван и какие имел параметры.
Шпионы полезны для тестирования устаревшего кода. Но если приходится использовать шпион для частичного моделирования класса, значит, класс выполняет слишком много действий. Это идет вразрез с принципом единой ответственности.
Создание моков с помощью Mockito API
Библиотека Mockito позволяет создавать mock-объекты разными методами:
- с применением расширения @ExtendWith(MockitoExtension.class) для JUnit 5 в сочетании с аннотацией @Mock;
- помощью статического метода mock();
- использованием аннотации @Mock.
При использовании аннотации @Mock нужно подготовить к работе аннотированные поля. Расширение MockitoExtension делает это, вызывая статический метод MockitoAnnotations.initMocks().
Разберем использование методов на модели данных:
package com.example.junit5;
public class Database public boolean isAvailable() return false;
>
public int getUniqueId() return 45;
>
>
package com.example.junit5;
public class Service private Database database;
public Service(Database database) this.database = database;
>
public boolean query(String query) return database.isAvailable();
>
@Override
public String toString() return «Используется база данных с ID: » + String.valueOf(database.getUniqueId());
>
>
Модульный тест в Mockito для объекта Database может выглядеть так:
package com.example.junit5;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class ServiceTest @Mock
Database databaseMock;
@Test
public void testQuery() assertNotNull(databaseMock);
when(databaseMock.isAvailable()).thenReturn(true);
Service t = new Service(databaseMock);
boolean check = t.query(«* from t»);
assertTrue(check);
>
>
Код теста выполняет действия:

- дает Mockito указание создать макеты на основе аннотации @Mock — для этого требуется JUnit 5. Если используется другая версия JUnit, нужно вызвать Mock.init() в методе setup;
- сообщает Mockito, что нужно создать фиктивный экземпляр базы данных — databaseMock;
- настраивает Mock на возврат true при вызове его метода isAvailable;
- выполняет код тестируемого класса;
- утверждает, что вызов метода вернул true.
Настройка возвращаемых значений методов
Mockito API позволяет настраивать возвращаемые значения методов, которые вызываются для фиктивных объектов. Неопределенные вызовы методов возвращают пустые значения:
- null для объектов;
- 0 для чисел;
- false для логических значений;
- пустые коллекции для коллекций.
Использование when().thenReturn() и when().thenThrow()
Моки могут возвращать различные значения в зависимости от аргументов, переданных в метод. Цепочка методов when(…).thenReturn(…) используется для указания возвращаемого значения для вызова метода с заранее заданными параметрами. Для возврата значений также можно использовать такие методы, как anyString или anyInt.
Создание фиктивных финальных классов и статических методов
После того как библиотека mockito-inline пришла на смену mockito-core, у пользователей появилась возможность создавать моки финальных классов и статических методов. Предположим, в приложении есть такой финальный класс:
final class FinalClass public final String finalMethod() < return «строка текста»; >
>
С помощью приведенного ниже кода можно создать мок этого класса:
package com.example.junit5;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class MockitoMockFinal @Test
public void testMockFinal(@Mock FinalClass finalMocked) assertNotNull(finalMocked);
>
@Test
public void testMockFinalViaMockStatic() MockedStatic mockStatic = Mockito.mockStatic(FinalClass.class);
assertNotNull(mockStatic);
>
>
Mockito делает код тестов проще и понятнее благодаря использованию фиктивных интерфейсов, прослушивающих вызовов, сопоставителей и захватчиков аргументов. Но, как и любой другой мощный инструмент, он должен использоваться правильно, чтобы быть максимально полезным.
Тестировщик-автоматизатор
Как ворваться в IT, даже если вы не умеете программировать? Стать тестировщиком. Для старта достаточно базовых знаний ПК. А начать работать можно уже через 4 месяца обучения.

Статьи по теме:
Saved searches
Use saved searches to filter your results more quickly
Cancel Create saved search
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
License
samokat-oss/performance-mockserver
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Switch branches/tags
Branches Tags
Could not load branches
Nothing to show
Could not load tags
Nothing to show
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Cancel Create
- Local
- Codespaces
HTTPS GitHub CLI
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more about the CLI.
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
Latest commit message
Commit time
README.md
сервис-заглушка на базе mockserver
Для реализации собственных заглушек нужно добавить в директорию org.samokat.performance.mockserver.mocks класс с ожиданиями по примеру Croissant.java или BananaBread.java . Один класс представляет полную конфигурацию заглушки. Также стоит добавить в org.samokat.performance.mockserver.core.initializer.CommandSwitcher инициализацию вашей конфигурации по примеру.
Метрики mockserver — http://localhost:1080/mockserver/metrics
Дашборд для отладки — http://localhost:1080/mockserver/dashboard
Помимо конфигураций описываемых в классах директории org.samokat.performance.mockserver.mocks релизовано:
- заглушка SMTP по порту 587
- заглушка graphql для экстернал полей (пример использования в BananaBread.java )
- метрики micrometer — http://localhost:8080/prometheus
Замените значение для team : croissant, bananabread или индентификатор вашей заглушки
docker build -t mock . docker run --name mock -p 587:587 -p 1080:1080 -p 8080:8080 -it mock:latest java -jar -Dteam= -Dloglevel=ERROR run.jar
Mock-сервисы для тестирования: How to use + Quick start
В подавляющем большинстве этот термин знаком всем и его сущность ни для кого не является секретом. Но, по традиции, все же лучше начать с определения:
11 показов
14K открытий
Заглушка — это небольшая часть кода, которая заменяет собой другой компонент во время тестирования. Преимущество использования заглушки заключается в том, что она возвращает последовательные результаты, упрощая написание теста. Тесты можно выполнять, даже если другие компоненты пока не работают.
В тестировании мы используем заглушки для имитации работы внешней системы. Заглушка приходится как нельзя кстати, когда мы ожидаем получить конкретный ответ на конкретный запрос. И вместо того, чтобы на самом деле отправлять этот запрос вовне, мы подкладываем нужный нам ответ.
На хабре достаточно статей по данной тематике. Наш QA-инженер–Николай – хочет остановиться на кратком руководстве для старта с общим обзором и примерами по одним из самых популярных инструментов. Дабы была возможность быстро определить перечень используемых инструментов и в дальнейшем продолжить уже их более углубленное изучение.
В данной статье будут приведены примеры с локальным развертыванием. Этот вариант идеально подойдет, если тестируемое приложение развернуто на рабочей машине. Если же стоит задача развернуть заглушку для удаленного сервиса, тут лучше обратиться к девопсам/администраторам. Т.к. политика безопасности не всегда дает доступ на сервер с крутящимся на нем приложением, а перед тем как будущая заглушка начнет отрабатывать – сервис придется перенастроить и перезагрузить. Иными словами сломать. Еще ни одного тестировщика за такие фокусы не похвалили. Потому в данной статье этот вопрос подниматься не будет.
Немного теории
Существует несколько видов объектов, которые позволяют симулировать поведение реальных объектов во время тестирования:
- Dummy — пустые объекты, которые передаются в вызываемые методы, но не используются. Предназначены лишь для заполнения параметров методов.
- Fake — объекты, которые имеют реализации, но в таком виде, который делает их неподходящими для использования в рабочей ситуации.
- Stub — предоставляют заранее заготовленные ответы на вызовы во время теста и не отвечают ни на какие другие вызовы, которые не требуются в тесте.
- Mock — объекты, которые заменяют реальный объект в условиях теста и позволяют проверять вызовы своих методов. Содержат заранее подготовленные описания вызовов, которые они ожидают получить. Применяются в основном для тестирования поведения пользователя.
Нас интересуют последние два вида, т.к. в тестировании мы и занимаемся тем, что имитируем и эмулируем работу реальных пользователей.
Старый и всем давно известный инструмент. Пригоден как для тестирования SOUP, так и REST сервисов, автоматизации их проверок и создания заглушек.
Для тех, кто все еще путается:
REST и SOAP не сопоставимы!
— REST — это архитектурный стиль, оперирующий JSON через HTTP.
— SOAP — это формат обмена XML сообщениями с ограничениями по структуре сообщений через HTTP.
Рассмотрим на примере REST сервиса. Для SOAP шаги будут идентичными и не вызовут особых трудностей.
При первом запуске автоматически всплывает окно Endpoint Explorer, в котором необходимо указать сам запрос и необходимые для работы заголовки:
После пробного запроса получаем ошибку, что такой ресурс не существует. Сюда же можно отнести случай, когда сервис есть, но возвращает не совсем то, что нужно:
