🧠 Вайб-кодинг: что это и как это влияет на разработку
Вайб-кодинг — это когда разработчик описывает задачу на естественном языке, а AI генерирует код. Это ускоряет процесс, но важно контролировать качество.
🚧 Проблема: сгенерированный код может быть неэффективным или иметь дыры в безопасности.
🎯 Что нужно учитывать при использовании вайб-кодинга:
— Быстрое создание прототипов
— Доступность для людей без технического образования
— Риски качества и безопасности кода
🔗 Подробнее о вайб-кодинге в статье
🐸 Библиотека джависта #буст
Вайб-кодинг — это когда разработчик описывает задачу на естественном языке, а AI генерирует код. Это ускоряет процесс, но важно контролировать качество.
🚧 Проблема: сгенерированный код может быть неэффективным или иметь дыры в безопасности.
🎯 Что нужно учитывать при использовании вайб-кодинга:
— Быстрое создание прототипов
— Доступность для людей без технического образования
— Риски качества и безопасности кода
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5🌚5❤3👍1
JOL — это инструмент от тех же разработчиков, что и JMH, и он помогает понять, как Java хранит объекты в памяти. Особенно полезен при оптимизации производительности и снижении потребления памяти.
📌 Что умеет JOL:
— Показывает внутреннюю структуру объектов Java (поля, пэддинг, смещения)
— Помогает исследовать выравнивание, заполнение и особенности layout'а объектов в разных JVM
— Учитывает влияние флагов типа -XX:ObjectAlignmentInBytes
— Есть аннотации и API для анализа объектов прямо из кода
— Поддерживает анализ "на месте" без запуска внешнего инструмента
🧠 Особенно актуально, если вы работаете с большим количеством данных, кастомными структурами или high-load системами. Понимание того, что реально занимает память, помогает сократить её расход без магии.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤3🔥3
Когда проект обрастает модулями, библиотеками и зависимостями, легко потерять нить. Dependency Analyzer помогает навести порядок в зависимостях и избавить проект от хлама.
🔹 Что делает
— Показывает все зависимости (включая транзитивные) в виде дерева
— Помогает обнаружить дублирующиеся зависимости, неиспользуемые библиотеки и конфликты версий
— Даёт рекомендации по удалению или замене
🔹 Зачем это нужно
— Упрощает анализ pom.xml или build.gradle — не нужно гадать, откуда взялась та или иная версия
— Помогает оптимизировать сборку и ускорить CI
— Снижает риски уязвимостей за счёт удаления неиспользуемых библиотек
🔹 Как использовать
— Откройте окно Maven/Gradle
— Нажмите кнопку Analyze Dependencies.
— IDEA покажет дерево с путями, версиями и проблемами
— Можно быстро перейти к конфигурации и исправить
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍4🔥1
Если вы когда-либо писали плагины, делали автоконфигурацию или искали классы с аннотациями — вам пригодится ClassGraph. Это быстрый и гибкий инструмент для сканирования classpath'а, аналог Reflections, но с куда лучшей производительностью и расширенной функциональностью.
📌 Что умеет ClassGraph:
— Находит классы по аннотациям, интерфейсам, суперклассам
— Позволяет искать ресурсы, inner-классы, модули, методы и поля
— Работает с JAR-файлами, модулями JPMS, Android, OSGi и даже нестандартной загрузкой классов
— Позволяет делать глубокий анализ зависимостей и иерархий
— Поддерживает черный/белый список пакетов (include/exclude)
⚡️ Почему лучше, чем Reflections:
— Существенно быстрее при сканировании большого classpath
— Умнее — может обрабатывать class-loader’ы, не теряя контекста
— Поддерживает более новые фичи JVM, включая модули (Java 9+)
— Активно поддерживается и обновляется
🧠 Полезно для:
— Фреймворков с динамической загрузкой
— Плагинных систем
— Анализа и визуализации зависимостей
— Разработки DI-контейнеров, автосканеров и DSL'ов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3❤2
Нужна быстрая интеграция с платежной системой? Используйте AI, чтобы автоматизировать подключение Stripe для безопасной обработки транзакций.
📝 Промпт:
Generate a Stripe payment integration for a Spring Boot 3 application.
— Set up Stripe API keys and configure them in application.properties.
— Implement StripePaymentService to handle payment requests using Stripe.create() for charges.
— Set up webhook endpoints to listen for payment status updates (e.g., success, failure).
— Integrate secure tokenization of credit card data using Stripe’s Java SDK.
— Handle errors gracefully and provide transaction feedback to users.
— Implement recurring payments using Stripe Subscriptions API for subscription-based models.
— Добавьте
Set up customer data storage with Stripe’s Customer objects to manage users’ payment methods
для управления способами оплаты пользователей.— Добавьте
Enable refund processing via Stripe API for failed or canceled transactions
для неудачных или отменённых транзакций.#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2❤1
🧠 Интеграция платежных систем
Банковская инфраструктура всё чаще становится ядром инноваций: интеграция с национальными системами быстрых платежей (как SEPA Instant) уже не просто конкурентное преимущество — это жизненная необходимость.
🔍 Почему это важно?
— Техническая сложность
Нужна событийно-управляемая (event‑driven) архитектура, очередь сообщений, надёжный асинхронный обмен между микросервисами.
— Надёжность и безопасность
Минимизация простоев, обеспечение отказоустойчивости и защита от сбоев — требования жёсткие, особенно при обработке тысяч транзакций в секунду.
— Перспективы
Интеграция с SEPA Instant и другими инфраструктурными провайдами меняет требования к архитектуре backend-систем — это скилл будущего для Java-инженеров.
🎯 Что внутри:
— Как строится архитектура интеграции банковской платформы с системами мгновенных платежей
— Почему event‑driven подход критически важен
— Какие проблемы решаются: масштабирование, отказоустойчивость, скорость
— Реальный опыт backend-разработчика, работавшего с SEPA Instant и банковскими сервисами
🔗 Подробнее в статье
🐸 Библиотека джависта
#буст
Банковская инфраструктура всё чаще становится ядром инноваций: интеграция с национальными системами быстрых платежей (как SEPA Instant) уже не просто конкурентное преимущество — это жизненная необходимость.
🔍 Почему это важно?
— Техническая сложность
Нужна событийно-управляемая (event‑driven) архитектура, очередь сообщений, надёжный асинхронный обмен между микросервисами.
— Надёжность и безопасность
Минимизация простоев, обеспечение отказоустойчивости и защита от сбоев — требования жёсткие, особенно при обработке тысяч транзакций в секунду.
— Перспективы
Интеграция с SEPA Instant и другими инфраструктурными провайдами меняет требования к архитектуре backend-систем — это скилл будущего для Java-инженеров.
🎯 Что внутри:
— Как строится архитектура интеграции банковской платформы с системами мгновенных платежей
— Почему event‑driven подход критически важен
— Какие проблемы решаются: масштабирование, отказоустойчивость, скорость
— Реальный опыт backend-разработчика, работавшего с SEPA Instant и банковскими сервисами
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤1👍1
Работаете с классом на 500 строк? Теряетесь в методах и полях? Structure Tool Window помогает быстро сориентироваться в любом файле.
🔹 Что делает
— Показывает структуру текущего файла: методы, поля, вложенные классы
— Подсвечивает override-методы, конструкторы, аннотации
— Поддерживает навигацию и поиск по элементам
— Работает для Java, Kotlin, XML, и даже .properties
🔹 Зачем это нужно
— Быстро находите нужный метод без скроллинга
— Помогает понять, как устроен чужой код
— Ускоряет навигацию по большим классам и конфигурациям
🔹 Как использовать
— Alt+7 (или Cmd+7 на macOS) — откроет Structure
— Можно настроить сортировку, группировку и фильтры
— Клик — и вы уже в нужном месте кода
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤3🔥2
S3-совместимое хранилище (AWS S3, MinIO, Yandex Object Storage и т.п.) — удобный способ хранить файлы вне приложения. Подключим его к Spring Boot и реализуем минимальный upload/download.
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.25.60</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
ИЛИ
implementation 'software.amazon.awssdk:s3:2.25.60'
implementation 'org.springframework.boot:spring-boot-starter-web'
s3:
region: eu-central-1
accessKey: minioadmin
secretKey: minioadmin
bucket: demo-bucket
spring:
servlet:
multipart:
max-file-size: 20MB
max-request-size: 20MB
@Configuration
public class S3Config {
@Bean
public S3Client s3Client(S3Props props) {
var builder = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(props.accessKey(), props.secretKey())))
.region(Region.of(props.region()))
.httpClientBuilder(UrlConnectionHttpClient.builder());
if (props.endpoint() != null && !props.endpoint().isBlank()) {
builder = builder
.endpointOverride(java.net.URI.create(props.endpoint()))
.serviceConfiguration(S3Configuration.builder()
.pathStyleAccessEnabled(props.pathStyleAccess())
.build());
}
return builder.build();
}
@Bean
public S3Props s3Props(org.springframework.core.env.Environment env) {
return new S3Props(
env.getProperty("s3.endpoint"),
env.getProperty("s3.region", "eu-central-1"),
env.getProperty("s3.accessKey"),
env.getProperty("s3.secretKey"),
env.getProperty("s3.bucket", "demo-bucket"),
Boolean.parseBoolean(env.getProperty("s3.pathStyleAccess", "true"))
);
}
public record S3Props(String endpoint, String region, String accessKey,
String secretKey, String bucket, boolean pathStyleAccess) {}
}
@Service
@RequiredArgsConstructor
public class S3StorageService {
private final S3Client s3;
private final S3Config.S3Props props;
public String upload(String originalName, String contentType, byte[] bytes) {
String key = UUID.randomUUID() + "_" + originalName;
s3.putObject(PutObjectRequest.builder()
.bucket(props.bucket())
.key(key)
.contentType(contentType)
.build(),
RequestBody.fromBytes(bytes));
return key;
}
public byte[] download(String key) {
GetObjectResponse[] meta = new GetObjectResponse[1];
try (var resp = s3.getObject(GetObjectRequest.builder()
.bucket(props.bucket()).key(key).build())) {
meta[0] = resp.response();
return resp.readAllBytes();
} catch (Exception e) {
throw NoSuchKeyException.builder().message("Object not found: " + key).build();
}
}
public void createBucketIfMissing() {
var bucket = props.bucket();
var exists = s3.listBuckets().buckets().stream().anyMatch(b -> b.name().equals(bucket));
if (!exists) s3.createBucket(CreateBucketRequest.builder().bucket(bucket).build());
}
}
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍5🔥3
Нужна быстрая интеграция с системой оповещений для отправки уведомлений по электронной почте? Используйте AI, чтобы автоматизировать подключение почтового сервиса и эффективно управлять рассылками.
📝 Промпт:
Generate an email notification system integration for a Spring Boot 3 application.
— Set up SMTP configuration in application.properties with email provider details (e.g., Gmail, SendGrid).
— Implement EmailService to send notifications using JavaMailSender and MimeMessage.
— Create a method to send transactional emails (e.g., order confirmation, password reset).
— Integrate email templates using Thymeleaf or FreeMarker for dynamic content generation.
— Set up email queues using Spring’s @Async to process notifications asynchronously.
— Handle email failures gracefully with retry mechanisms and user feedback.
— Добавьте
Send welcome emails with a personalized subject and content for new user registrations
для приветственных писем.— Добавьте
Implement email subscription management for users to opt-in/opt-out from specific notifications
для управления подписками пользователей.#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3🥱3❤2👏2
🚀 Индексы в PostgreSQL
Когда сервис начинает работать с десятками миллионов строк, простое findById уже не выглядит «мгновенным». Тут в игру вступают индексы.
🔍 Что такое индекс
Индекс в PostgreSQL — это отдельная структура данных, которая позволяет находить строки намного быстрее, чем полный перебор таблицы.
⚡️ Типы индексов и когда применять
— B-Tree (по умолчанию)
Отлично работает для операций =, <, >, ORDER BY.
Частый кейс: поиск по id, created_at, username.
— GIN (Generalized Inverted Index)
Для jsonb, массивов и полнотекстового поиска.
Например, поиск по тегам или WHERE metadata @> '{"os":"android"}'.
— GiST (Generalized Search Tree)
Для геоданных, поиска по диапазонам (tsrange, daterange).
— Hash Index
Для очень быстрого поиска по точному совпадению, но реже нужен (B-Tree почти всегда быстрее).
⚠️ На что обратить внимание
— Индекс ускоряет SELECT, но замедляет INSERT/UPDATE/DELETE (нужно обновлять и таблицу, и индекс).
— Слишком много индексов = «смерть от оптимизации». Держите баланс.
— Никогда не делайте индексы «на всё подряд». Индекс должен соответствовать реальным запросам.
💬 А вы чаще оптимизируете запросы через индексы или через переписывание логики?
🐸 Библиотека джависта
#буст
Когда сервис начинает работать с десятками миллионов строк, простое findById уже не выглядит «мгновенным». Тут в игру вступают индексы.
🔍 Что такое индекс
Индекс в PostgreSQL — это отдельная структура данных, которая позволяет находить строки намного быстрее, чем полный перебор таблицы.
⚡️ Типы индексов и когда применять
— B-Tree (по умолчанию)
Отлично работает для операций =, <, >, ORDER BY.
Частый кейс: поиск по id, created_at, username.
CREATE INDEX idx_user_email ON users(email);
— GIN (Generalized Inverted Index)
Для jsonb, массивов и полнотекстового поиска.
Например, поиск по тегам или WHERE metadata @> '{"os":"android"}'.
CREATE INDEX idx_logs_metadata ON logs USING gin (metadata jsonb_path_ops);
— GiST (Generalized Search Tree)
Для геоданных, поиска по диапазонам (tsrange, daterange).
CREATE INDEX idx_places_geom ON places USING gist (geom);
— Hash Index
Для очень быстрого поиска по точному совпадению, но реже нужен (B-Tree почти всегда быстрее).
CREATE INDEX idx_sessions_sid ON sessions USING hash (session_id);
⚠️ На что обратить внимание
— Индекс ускоряет SELECT, но замедляет INSERT/UPDATE/DELETE (нужно обновлять и таблицу, и индекс).
— Слишком много индексов = «смерть от оптимизации». Держите баланс.
— Никогда не делайте индексы «на всё подряд». Индекс должен соответствовать реальным запросам.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥4❤3🤔1
⚙️ Async Profiler
Async Profiler — это современный профайлер для JVM, который показывает, где именно «горит» CPU и где происходят утечки памяти. В отличие от классических профайлеров, он использует низкоуровневые возможности ОС (perf, JVMTI) и практически не влияет на производительность.
📌 Что умеет:
— Делает CPU и allocation flame graph'ы
— Минимальный overhead
— Поддерживает анализ Java и нативного кода вместе
— Умеет снимать снапшоты и строить красивые SVG-отчёты
🧠 Особенно полезен, если у вас микросервисы или приложения с нагрузкой 24/7 — можно ловить узкие места без остановки сервиса.
🔗 Async Profiler на GitHub
🐸 Библиотека джависта
#буст
Async Profiler — это современный профайлер для JVM, который показывает, где именно «горит» CPU и где происходят утечки памяти. В отличие от классических профайлеров, он использует низкоуровневые возможности ОС (perf, JVMTI) и практически не влияет на производительность.
📌 Что умеет:
— Делает CPU и allocation flame graph'ы
— Минимальный overhead
— Поддерживает анализ Java и нативного кода вместе
— Умеет снимать снапшоты и строить красивые SVG-отчёты
🧠 Особенно полезен, если у вас микросервисы или приложения с нагрузкой 24/7 — можно ловить узкие места без остановки сервиса.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3👏1
В JUnit 5 появилась интересная аннотация @ClassTemplate. Она полезна, когда один и тот же набор тестов нужно выполнить в разных контекстах. Например: проверить класс с разными локалями, флагами или окружениями.
Обычно в таких случаях мы либо дублируем тестовые классы, либо городим параметризованные тесты. Но @ClassTemplate позволяет описать тест один раз, а запускать его несколько раз — каждый раз в новом окружении.
— Помечаем тестовый класс @ClassTemplate.
— Регистрируем ClassTemplateInvocationContextProvider, который возвращает список «контекстов» (например, en/it).
— JUnit прогоняет один и тот же класс для каждого контекста.
— Есть Greeter, который должен возвращать приветствие по-английски и по-русски.
— Мы пишем один тест → JUnit запускает его дважды: для en и для ru.
— В отчёте два результата, код теста при этом один.
— Работает начиная с JUnit 5.13.
— Для читаемых логов удобнее запускать через JUnit Console Launcher.
— Отличается от @TestTemplate тем, что переиспользует весь класс, а не отдельные методы.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🔥4
🔧 Как устроена масштабируемая система
Представьте, что вам нужно обрабатывать миллионы запросов и файлов — как это сделать эффективно? Ответ кроется в правильном проектировании архитектуры.
Вот ключевые компоненты:
🔹 DNS — запросы перенаправляются на нужный сервер.
🔹 Балансировка нагрузки — равномерное распределение трафика между серверами для избежания перегрузок.
🔹 Масштабирование — использование распределенных сервисов и кеширования для работы с большими объемами данных.
🔹 Обработка медиа — загрузка и обработка изображений/видео с последующей обработкой метаданных.
🔹 Базы данных — распределение данных и управление запросами для обеспечения высокой доступности.
Эти компоненты обеспечивают масштабируемость и надежность системы, позволяя обрабатывать любые объемы данных без потери производительности.
🐸 Библиотека джависта
#буст
Представьте, что вам нужно обрабатывать миллионы запросов и файлов — как это сделать эффективно? Ответ кроется в правильном проектировании архитектуры.
Вот ключевые компоненты:
🔹 DNS — запросы перенаправляются на нужный сервер.
🔹 Балансировка нагрузки — равномерное распределение трафика между серверами для избежания перегрузок.
🔹 Масштабирование — использование распределенных сервисов и кеширования для работы с большими объемами данных.
🔹 Обработка медиа — загрузка и обработка изображений/видео с последующей обработкой метаданных.
🔹 Базы данных — распределение данных и управление запросами для обеспечения высокой доступности.
Эти компоненты обеспечивают масштабируемость и надежность системы, позволяя обрабатывать любые объемы данных без потери производительности.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤4🔥1
Ну всё, хватит отдыхать 😁
Обсудим интересные фичи 21 java.
Переход на версию LTS — не просто "модно", а реальная возможность повысить продуктивность проекта. Вот на что стоит обратить внимание:
При миллионе одинаковых тестовых задач время получается следующее :
— FixedThreadPool : 33 мин.
— CachedThreadPool : 1:26 мин.
— VirtualThreadPerTask : всего 14 секунд
Производительность и масштабируемость на новом уровне.
Record-паттерны позволяют одновременно проверять тип и извлекать поля, свитчи стали мощнее — меньше кода, больше читаемости.
Минимальные задержки (sub-миллисекунды) и оптимальное управление памятью, что идеально для latency-чувствительных приложений.
Новый синтаксис для динамических строк (например, JSON-создание) создает меньше ошибок и улучшает читаемость.
Последовательные операции легко доступны: getFirst(), getLast(), reversed() — удобно и логично.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍7❤4😁1
Чёткая схема API помогает наладить диалог между провайдером и клиентом, а единый формат ошибок — избавить потребителей от хаоса в коде и лишних поводов для «боли».
🔹 В Spring Boot по умолчанию структура ошибок выглядит так:
{
"timestamp": "2021-15-08T14:32:17.947+0000",
"status": 500,
"error": "Internal Server Error",
"path": "/test"
}
Такая форма ответа не всегда содержит тип ошибки для обработки на клиенте, а также предоставляет мало контекста для формирования пользовательских сообщений.
🔹 Решение: разработать унифицированную структуру, например:
{
"error": {
"type": "USER_NOT_FOUND",
"message": "User with ID 12345 not found.",
"status": 500,
"path": "/integration/apps",
"timestamp": "2021-15-08T14:32:17.947+0000",
"data": {
"userId": "12345"
}
}
}
🔹 Как внедрить:
▪️ Создаём единое исключение AppException:
public final class AppException extends RuntimeException {
private final ErrorType type;
private Map<String, Object> data;
// конструктор и геттеры...
}
public enum ErrorType {
USER_NOT_FOUND(404), AUTHENTICATION_FAILED(401), …;
private final int status;
// геттеры...
}
▪️ Глобальный обработчик:
Используем @ControllerAdvice с @ExceptionHandler(AppException.class) для перехвата ошибок и возвращения QErrorResponse, содержащего нужную структуру
▪️ Обработка всех остальных ошибок:
Создаём свой ErrorController, заменяющий BasicErrorController, и возвращаем данные в таком же формате QErrorResponse:
@RestController
@RequestMapping("${server.error.path:${error.path:/error}}")
public class RestErrorController extends AbstractErrorController {
// логика формирования QErrorResponse…
}
Это гарантирует, что любые ошибки возвращаются в одинаковом формате .
🔹 Почему это важно:
— Унификация ответа облегчает обработку ошибок на клиенте.
— Контекст в data позволяет выдавать более понятные сообщения пользователю.
— Расширяемость дает возможность добавлять новые типы ошибок при сохранении консистентности.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍5🔥3🥱1
Хотите ускорить написание кода и избежать повторений? Используйте Live Templates для создания шаблонов кода, которые можно вставлять за пару кликов.
🔹 Что делает
— Позволяет создавать шаблоны кода для часто используемых конструкций
— Поддерживает параметры и автозамену (например, поля и методы)
— Работает для Java, Kotlin, HTML, и других языков
🔹 Зачем это нужно
— Сокращает время на написание повторяющихся конструкций
— Уменьшает количество ошибок за счёт предсказуемых шаблонов
— Улучшает производительность и помогает не забыть важные моменты
🔹 Как использовать
— Ctrl+J (или Cmd+J на macOS) — откроет список шаблонов
— Можно создать свой шаблон в Settings → Editor → Live Templates
— Настройте шаблон под ваши нужды, и используйте его с удобным сокращением
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2🔥2
🛠 Грейдинг умер. На собесах теперь правит ИИ
IT-рынок в 2025 уже не тот. Забудьте сказки про «сменю компанию — сразу +100 к к зарплате». Всё: грейдинг сдулся, вакансий меньше, а на собеседованиях вас может встречать не только тимлид, но и искусственный интеллект.
🚧 Рынок стал осторожнее:
— Грейды больше не гарантируют рост.
— Джоб-борды захламлены нерелевантными откликами.
— Компании проверяют кандидатов дольше и жёстче.
🔗 Подробнее о в статье
🐸 Библиотека джависта
#буст
IT-рынок в 2025 уже не тот. Забудьте сказки про «сменю компанию — сразу +100 к к зарплате». Всё: грейдинг сдулся, вакансий меньше, а на собеседованиях вас может встречать не только тимлид, но и искусственный интеллект.
🚧 Рынок стал осторожнее:
— Грейды больше не гарантируют рост.
— Джоб-борды захламлены нерелевантными откликами.
— Компании проверяют кандидатов дольше и жёстче.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱15❤4👍1🔥1💯1
В тестировании часто встречаются термины Mock, Stub и Fake. Все они относятся к подмене реальных зависимостей, но выполняют разные роли. Давайте разберемся, в чем их отличие и когда применять каждый из них.
Мок — это объект, поведение которого мы заранее определяем. Мы говорим, какие методы должны быть вызваны, какие значения возвращать, и проверяем, были ли вызваны эти методы в тесте.
📝 Пример:
@Test
public void testService() {
MyService service = mock(MyService.class);
when(service.getData()).thenReturn("Hello, World");
assertEquals("Hello, World", service.getData());
}
Идеальный выбор для тестирования взаимодействий между компонентами, когда нужно удостовериться, что объект выполняет определенные действия в процессе работы программы.
Стаб — это объект, который возвращает заранее заданные значения. Он просто заменяет реальную зависимость, не проверяя, как она используется, а только подставляет нужные значения.
📝 Пример:
@Test
public void testService() {
MyService service = new StubService();
assertEquals("Mocked Data", service.getData());
}
Полезен, когда необходимо изолировать тестируемый компонент от других, например, при тестировании бизнес-логики, где важно не загружать реальные сервисы.
Фейк — это объект, который имеет реальное поведение, но в упрощенной или в ограниченной форме. Он может быть использован вместо реального объекта, но не имеет всех возможностей или работает быстрее.
📝 Пример:
public class FakeDatabase implements Database {
private Map<String, String> data = new HashMap<>();
public void insert(String key, String value) {
data.put(key, value);
}
public String get(String key) {
return data.get(key);
}
}
Например, можно использовать фейк для имитации базы данных, чтобы проверить логику взаимодействия с ней без необходимости запускать полноценное хранилище данных.
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10😁5❤2🔥1