[Spring] End-to-End 와 통합테스트

김민범·2024년 12월 14일

Spring

목록 보기
25/29

통합 테스트는 일반적으로 애플리케이션의 여러 계층이 함께 동작하는지 확인하기 위한 테스트이다. 따라서 request -> controller -> service -> repository까지 실제로 호출하는 엔드 투 엔드(End-to-End) 테스트가 주된 목적이다. 그렇다면 "서비스에 대한 통합 테스트"란 어떤 의미인지 혼란스러울 수 있다.

1. "서비스에 대한 통합 테스트"의 의미

"서비스에 대한 통합 테스트"는 다음 두 가지로 이해할 수 있다:

  1. 서비스 계층 중심의 통합 테스트

    • 서비스 계층그 하위 계층(리포지토리, 외부 API 등) 간의 상호작용이 제대로 동작하는지 검증하는 테스트이다.
    • 이 경우, 컨트롤러를 포함하지 않고 서비스 계층에 초점을 맞춘다.
    • 즉, service -> repository 또는 service -> external API서비스 계층과 통합된 하위 계층을 검증한다.
  2. 서비스 계층이 복잡한 비즈니스 로직을 포함하는 경우

    • 서비스 계층 자체가 독립적으로 복잡한 비즈니스 로직을 처리한다면, 이를 통합적으로 테스트할 필요가 있다.
    • 리포지토리, 외부 API와 같은 하위 계층의 실제 동작을 포함한 상태에서 서비스 로직이 기대대로 동작하는지 확인한다.

2. 서비스 통합 테스트의 일반적인 구성

"서비스에 대한 통합 테스트"는 컨트롤러를 제외하고, 서비스와 하위 계층 간의 상호작용에 초점을 맞춘다.

예제: 서비스 통합 테스트

@SpringBootTest
@Transactional // 테스트 후 데이터 롤백
public class ReservationServiceIntegrationTest {

    @Autowired
    private ReservationService reservationService;

    @Autowired
    private ReservationRepository reservationRepository;

    @Test
    void testCreateReservation() {
        // given
        ReservationRequestDto request = new ReservationRequestDto("itemName", "userNickname");

        // when
        ReservationResponseDto response = reservationService.createReservation(request);

        // then
        assertNotNull(response.getId());
        assertEquals("itemName", response.getItemName());
        assertEquals("userNickname", response.getUserNickname());

        // 데이터가 실제로 저장되었는지 검증
        Reservation savedReservation = reservationRepository.findById(response.getId()).orElseThrow();
        assertEquals("itemName", savedReservation.getItemName());
    }
}

특징

  1. 컨트롤러를 호출하지 않는다:

    • 테스트 범위는 서비스 계층부터 시작하여 리포지토리 계층까지이다.
    • 따라서 컨트롤러 로직은 MockMvc를 통해 별도로 테스트한다.
  2. 실제 데이터베이스 연동:

    • 리포지토리와의 상호작용이 실제로 이루어진다(H2 등 임시 DB 사용).
  3. 서비스 계층의 통합 로직 검증:

    • 서비스 계층이 리포지토리나 외부 API와 올바르게 동작하는지 검증한다.

3. 서비스 통합 테스트와 단위 테스트의 차이점

특징서비스 단위 테스트서비스 통합 테스트
테스트 범위서비스 계층만 테스트 (Mock으로 하위 계층 대체)서비스 계층 + 리포지토리 또는 외부 API와 통합
의존성하위 계층(리포지토리, API 등)은 Mock 또는 Stub 사용실제 리포지토리 또는 외부 API 연동
속도빠르다 (Mock 사용으로 DB 접근 없음)느리다 (실제 DB 또는 외부 호출 필요)
테스트 목적비즈니스 로직 단위 테스트서비스 계층과 하위 계층 간 상호작용 검증
적용 사례간단한 로직, 하위 계층과 무관한 비즈니스 로직 검증복잡한 로직 또는 리포지토리와 통합된 비즈니스 로직

4. 왜 서비스 통합 테스트가 필요한가?

  1. 리포지토리와의 상호작용 확인:

    • 서비스 계층이 리포지토리 계층과 데이터를 올바르게 저장, 조회, 삭제하는지 확인하기 위함이다.
  2. 외부 API 호출 확인:

    • 서비스 계층이 외부 API와의 통합에서 올바르게 동작하는지 검증하기 위함이다.
  3. 복잡한 비즈니스 로직 검증:

    • 서비스 계층에서 여러 리포지토리 호출이나 데이터 조작이 이루어진다면, 이러한 로직이 실제로 기대대로 동작하는지 확인할 필요가 있다.

5. 서비스 통합 테스트의 예시: 다양한 계층 연동

예제: 리포지토리와 외부 API 연동 테스트

@SpringBootTest
@Transactional
public class PaymentServiceIntegrationTest {

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private PaymentRepository paymentRepository;

    @MockBean // 외부 API는 Mock 처리
    private ExternalPaymentGateway paymentGateway;

    @Test
    void testProcessPayment() {
        // given
        PaymentRequest request = new PaymentRequest(100, "USD");
        when(paymentGateway.process(any(PaymentRequest.class))).thenReturn(new PaymentResponse("SUCCESS"));

        // when
        PaymentResponse response = paymentService.processPayment(request);

        // then
        assertEquals("SUCCESS", response.getStatus());

        // 데이터베이스 저장 확인
        Payment savedPayment = paymentRepository.findAll().get(0);
        assertEquals(100, savedPayment.getAmount());
        assertEquals("USD", savedPayment.getCurrency());
    }
}

6. 서비스 통합 테스트와 엔드 투 엔드 테스트의 차이

  • 서비스 통합 테스트:

    • service -> repository 또는 service -> external API까지의 상호작용을 테스트한다.
    • 컨트롤러 계층은 포함하지 않는다.
    • 주요 목표는 서비스 계층과 하위 계층 간의 통합을 확인하는 것이다.
  • 엔드 투 엔드 테스트 (E2E):

    • controller -> service -> repository -> DB까지의 모든 계층이 포함된다.
    • 실제 요청과 응답을 통해 전체 애플리케이션의 동작을 검증한다.

7. 결론

  • "서비스에 대한 통합 테스트"는 서비스 계층과 그 하위 계층(리포지토리, 외부 API) 간의 상호작용을 테스트하는 것을 의미한다.
  • 컨트롤러를 포함하지 않고, 서비스 계층 중심으로 테스트를 수행한다.
  • 주로 복잡한 비즈니스 로직리포지토리 연동 또는 외부 API 호출을 검증하는 데 유용하다.
  • 서비스 통합 테스트는 단위 테스트와 엔드 투 엔드 테스트 사이의 중간 단계로, 테스트의 신뢰성과 유지보수성을 높이는 데 기여한다.

0개의 댓글