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의 검증 모드를 사용하여 이벤트 발행 횟수를 정확히 확인하세요. - 테스트 범위: 단위 테스트에서는 리스너 로직만 검증하고, 통합 테스트에서 전체 이벤트 흐름을 테스트하는 것이 좋습니다.