Community코딩 & 개발github.com

giuseppe-trisciuoglio/unit-test-application-events

Spring 애플리케이션 이벤트 단위 테스트를 위한 패턴을 제공합니다. ApplicationEventPublisher를 사용한 이벤트 발행 검증, @EventListener 애노테이션 동작 테스트, 비동기 이벤트 처리 확인을 지원합니다. 이벤트 리스너 테스트 작성, 애플리케이션 이벤트 모킹, Spring Boot 서비스에서 이벤트 발행 확인 시 사용하세요.

unit-test-application-events란 무엇인가요?

이 스킬은 Spring 애플리케이션에서 이벤트 기반 통신을 단위 테스트하는 방법을 제공합니다. 개발자는 ApplicationEventPublisher를 모킹하여 이벤트가 올바르게 발행되었는지 검증하고, @EventListener 애노테이션이 붙은 리스너 메서드가 의도한 대로 동작하는지 테스트할 수 있습니다. 또한 @Async 애노테이션과 결합된 비동기 이벤트 리스너의 동작을 검증하는 패턴도 포함되어 있어, Spring Boot 기반 마이크로서비스나 이벤트 드리븐 아키텍처에서 중요한 테스트 커버리지를 확보할 수 있습니다. 이 스킬은 Spring Framework 5.x 이상과 Spring Boot 2.x 이상을 지원하며, JUnit 5와 Mockito를 활용한 실용적인 코드 예제를 제공합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit/tree/main/skills/unit-test-application-events

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

unit-test-application-events은(는) 무엇을 하나요?

Spring 애플리케이션 이벤트 단위 테스트를 위한 패턴을 제공합니다. ApplicationEventPublisher를 사용한 이벤트 발행 검증, @EventListener 애노테이션 동작 테스트, 비동기 이벤트 처리 확인을 지원합니다. 이벤트 리스너 테스트 작성, 애플리케이션 이벤트 모킹, Spring Boot 서비스에서 이벤트 발행 확인 시 사용하세요.

개요

Spring의 애플리케이션 이벤트 메커니즘은 느슨한 결합을 유지하면서 컴포넌트 간 통신을 가능하게 합니다. 이 스킬은 이러한 이벤트 기반 통신을 안정적으로 테스트할 수 있는 방법을 제공합니다.

주요 기능

  • ApplicationEventPublisher 모킹: Mockito를 사용하여 ApplicationEventPublisher를 모킹하고 이벤트 발행을 검증합니다.
  • @EventListener 테스트: @EventListener 애노테이션이 붙은 리스너 메서드의 동작을 단위 테스트합니다.
  • 비동기 이벤트 처리: @Async와 결합된 이벤트 리스너의 비동기 동작을 검증합니다.

지원 플랫폼

  • Spring Framework 5.x 이상
  • Spring Boot 2.x 이상
  • JUnit 5
  • Mockito

사용 방법

1. ApplicationEventPublisher 모킹

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.ApplicationEventPublisher;

@ExtendWith(MockitoExtension.class)
class EventPublisherServiceTest {

    @Mock
    private ApplicationEventPublisher eventPublisher;

    @InjectMocks
    private EventPublisherService eventPublisherService;

    @Test
    void testEventPublishing() {
        // Given
        String data = "test data";

        // When
        eventPublisherService.publishEvent(data);

        // Then
        ArgumentCaptor<CustomEvent> eventCaptor = ArgumentCaptor.forClass(CustomEvent.class);
        verify(eventPublisher, times(1)).publishEvent(eventCaptor.capture());
        assertEquals(data, eventCaptor.getValue().getData());
    }
}

2. @EventListener 테스트

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class EventListenerTest {

    @Mock
    private SomeDependency someDependency;

    @InjectMocks
    private EventListener eventListener;

    @Test
    void testEventListenerHandlesEvent() {
        // Given
        CustomEvent event = new CustomEvent("test event");

        // When
        eventListener.handleCustomEvent(event);

        // Then
        verify(someDependency).process(event);
    }
}

3. 비동기 이벤트 리스너 테스트

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.concurrent.CompletableFuture;

@ExtendWith(MockitoExtension.class)
class AsyncEventListenerTest {

    @Mock
    private SomeService someService;

    @InjectMocks
    private AsyncEventListener asyncEventListener;

    @Test
    void testAsyncEventHandling() throws Exception {
        // Given
        CustomEvent event = new CustomEvent("async event");
    
        // When
        CompletableFuture<Void> future = asyncEventListener.handleAsyncEvent(event);
        future.get();  // 비동기 처리가 완료될 때까지 대기

        // Then
        verify(someService).processAsync(event);
    }
}

팁 및 모범 사례

  • ArgumentCaptor 사용: ArgumentCaptor를 활용하여 발행된 이벤트 객체의 특정 필드를 검증하세요.
  • 비동기 테스트: 비동기 이벤트 리스너를 테스트할 때는 CompletableFuture.get()을 사용하여 테스트가 완료될 때까지 대기하세요.
  • Mockito 검증: times(1), never() 등 Mockito의 검증 모드를 사용하여 이벤트 발행 횟수를 정확히 확인하세요.
  • 테스트 범위: 단위 테스트에서는 리스너 로직만 검증하고, 통합 테스트에서 전체 이벤트 흐름을 테스트하는 것이 좋습니다.

관련 리소스

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

giuseppe-trisciuoglio/aws-lambda-java-integration

Provides AWS Lambda integration patterns for Java with cold start optimization. Use when deploying Java functions to AWS Lambda, choosing between Micronaut and Raw Java approaches, optimizing cold starts below 1 second, configuring API Gateway or ALB integration, or implementing serverless Java applications. Triggers include "create lambda java", "deploy java lambda", "micronaut lambda aws", "java lambda cold start", "aws lambda java performance", "java serverless framework".

giuseppe-trisciuoglio/aws-lambda-php-integration

Provides AWS Lambda integration patterns for PHP with Symfony using the Bref framework. Creates Lambda handler classes, configures runtime layers, sets up SQS/SNS event triggers, implements warm-up strategies, and optimizes cold starts. Use when deploying PHP/Symfony applications to AWS Lambda, configuring API Gateway integration, implementing serverless PHP applications, or optimizing Lambda performance with Bref. Triggers include "create lambda php", "deploy symfony lambda", "bref lambda aws", "php lambda cold start", "aws lambda php performance", "symfony serverless", "php serverless framework".

giuseppe-trisciuoglio/aws-lambda-python-integration

Provides AWS Lambda integration patterns for Python with cold start optimization. Use when deploying Python functions to AWS Lambda, choosing between AWS Chalice and raw Python approaches, optimizing cold starts, configuring API Gateway or ALB integration, or implementing serverless Python applications. Triggers include "create lambda python", "deploy python lambda", "chalice lambda aws", "python lambda cold start", "aws lambda python performance", "python serverless framework".

giuseppe-trisciuoglio/aws-lambda-typescript-integration

Provides AWS Lambda integration patterns for TypeScript with cold start optimization. Use when creating or deploying TypeScript Lambda functions, choosing between NestJS framework and raw TypeScript approaches, optimizing cold starts, configuring API Gateway or ALB integration, or implementing serverless TypeScript applications. Triggers include "create lambda typescript", "deploy typescript lambda", "nestjs lambda aws", "raw typescript lambda", "aws lambda typescript performance".

giuseppe-trisciuoglio/aws-rds-spring-boot-integration

Provides patterns to configure AWS RDS (Aurora, MySQL, PostgreSQL) with Spring Boot applications. Configures HikariCP connection pools, implements read/write splitting, sets up IAM database authentication, enables SSL connections, and integrates with AWS Secrets Manager. Use when setting up RDS connections in Spring Boot, configuring connection pooling, or managing database credentials securely.

giuseppe-trisciuoglio/aws-sdk-java-v2-bedrock

Provides Amazon Bedrock patterns using AWS SDK for Java 2.x. Invokes foundation models (Claude, Llama, Titan), generates text and images, creates embeddings for RAG, streams real-time responses, and configures Spring Boot integration. Use when asking about Bedrock integration, Java SDK for AI models, AWS generative AI, Claude/Llama invocation, embeddings for RAG, or Spring Boot AI setup.

giuseppe-trisciuoglio/aws-sdk-java-v2-core

Provides AWS SDK for Java 2.x client configuration, credential resolution, HTTP client tuning, timeout, retry, and testing patterns. Use when creating or hardening AWS service clients, wiring Spring Boot beans, debugging auth or region issues, or choosing sync vs async SDK usage.

giuseppe-trisciuoglio/aws-sdk-java-v2-dynamodb

Provides Amazon DynamoDB patterns using AWS SDK for Java 2.x. Use when creating, querying, scanning, or performing CRUD operations on DynamoDB tables, working with indexes, batch operations, transactions, or integrating with Spring Boot applications.

giuseppe-trisciuoglio/aws-sdk-java-v2-kms

Provides AWS Key Management Service (KMS) patterns using AWS SDK for Java 2.x. Use when creating/managing encryption keys, encrypting/decrypting data, generating data keys, digital signing, key rotation, or integrating encryption into Spring Boot applications.

giuseppe-trisciuoglio/aws-sdk-java-v2-lambda

Provides AWS Lambda patterns using AWS SDK for Java 2.x. Use when invoking Lambda functions, creating/updating functions, managing function configurations, working with Lambda layers, or integrating Lambda with Spring Boot applications.

giuseppe-trisciuoglio/aws-sdk-java-v2-messaging

Provides AWS messaging patterns using AWS SDK for Java 2.x for SQS queues and SNS topics. Handles sending/receiving messages, FIFO queues, DLQ, subscriptions, and pub/sub patterns. Use when implementing messaging with SQS or SNS.

giuseppe-trisciuoglio/aws-sdk-java-v2-rds

Provides AWS RDS (Relational Database Service) management patterns using AWS SDK for Java 2.x. Use when creating, modifying, monitoring, or managing Amazon RDS database instances, snapshots, parameter groups, and configurations.

giuseppe-trisciuoglio/aws-sdk-java-v2-s3

Provides Amazon S3 patterns and examples using AWS SDK for Java 2.x. Use when working with S3 buckets, uploading/downloading objects, multipart uploads, presigned URLs, S3 Transfer Manager, object operations, or S3-specific configurations.

giuseppe-trisciuoglio/aws-sdk-java-v2-secrets-manager

Provides AWS Secrets Manager patterns for AWS SDK for Java 2.x, including secret retrieval, caching, rotation-aware access, and Spring Boot integration. Use when storing or reading secrets in Java services, replacing hardcoded credentials, or wiring secret-backed configuration into applications.

giuseppe-trisciuoglio/better-auth

Provides Better Auth integration patterns for NestJS backend and Next.js frontend with Drizzle ORM and PostgreSQL. Use when setting up Better Auth with NestJS backend, integrating Next.js App Router frontend, configuring Drizzle ORM schema, implementing social login (GitHub, Google), adding plugins (2FA, Organization, SSO, Magic Link, Passkey), implementing email/password authentication with session management, or creating protected routes and middleware.

giuseppe-trisciuoglio/chunking-strategy

Provides chunking strategies for RAG systems. Generates chunk size recommendations (256-1024 tokens), overlap percentages (10-20%), and semantic boundary detection methods. Validates semantic coherence and evaluates retrieval precision/recall metrics. Use when building retrieval-augmented generation systems, vector databases, or processing large documents.

giuseppe-trisciuoglio/clean-architecture

Provides implementation patterns for Clean Architecture, Hexagonal Architecture (Ports & Adapters), and Domain-Driven Design in Java 21+ Spring Boot 3.5+ applications. Use when structuring layered architectures, separating domain logic from frameworks, implementing ports and adapters, creating entities/value objects/aggregates, or refactoring monolithic codebases for testability and maintainability.

giuseppe-trisciuoglio/docs-updater

Provides automated documentation updates by analyzing git changes between the current branch and the last release tag. Performs git diff analysis to identify modifications, then updates README.md, CHANGELOG.md following Keep a Changelog standard, and discovers documentation folders for contextual updates. Use when preparing a release, maintaining documentation sync, or before creating a pull request. Triggers on "update docs", "update changelog", "sync documentation", "update readme", "prepare release documentation".

giuseppe-trisciuoglio/drawio-logical-diagrams

Creates professional logical flow diagrams and logical system architecture diagrams using draw.io XML format (.drawio files). Use when creating: (1) logical flow diagrams showing data/process flow between system components, (2) logical architecture diagrams representing system structure without cloud provider specifics, (3) BPMN process diagrams, (4) UML diagrams (class, sequence, activity), (5) data flow diagrams (DFD), (6) decision flowcharts, or (7) system interaction diagrams. This skill focuses on generic/abstract representations, not AWS/Azure-specific architectures (use aws-drawio-architecture-diagrams for cloud diagrams).

giuseppe-trisciuoglio/drizzle-orm-patterns

Provides comprehensive Drizzle ORM patterns for schema definition, CRUD operations, relations, queries, transactions, and migrations. Proactively use for any Drizzle ORM development including defining database schemas, writing type-safe queries, implementing relations, managing transactions, and setting up migrations with Drizzle Kit. Supports PostgreSQL, MySQL, SQLite, MSSQL, and CockroachDB.

관련 스킬