기술과 산업/언어 및 프레임워크

Spring Boot 고급 시리즈 7편 – REST API 통합 테스트 전략: MockMvc, RestAssured, TestContainer까지 실전 가이드

B컷개발자 2025. 4. 22. 15:30
728x90

Spring Boot에서 REST API를 테스트하는 전략을 정리했습니다. MockMvc, RestAssured, 통합 테스트 설계, TestContainer 적용 예제까지 실무 중심으로 구성했습니다.


Spring Boot 고급 시리즈 7편 – REST API 통합 테스트 전략: MockMvc, RestAssured, TestContainer까지 실전 가이드

서비스를 안정적으로 운영하기 위해선 테스트가 곧 문서이고, 계약이며, 생존 전략이 됩니다.
이번 편에서는 Spring Boot에서 REST API를 단계별로 테스트하는 전략,
그리고 각 단계에서 사용하는 주요 도구들(MockMvc, RestAssured, TestContainer 등)의 구현 방식과 특징을 상세히 살펴보겠습니다.


🧭 1. 왜 API 테스트 전략이 중요한가?

  • 신뢰성 확보: 코드 리팩토링 후에도 기능이 깨지지 않았음을 확인
  • 명세 검증: 실제 동작이 API 문서와 일치하는지 검증
  • 배포 안정성: CI/CD에서 자동화된 테스트로 운영 사고 예방
  • 협업의 기준선: API 테스트는 프론트/앱 개발자와의 약속

🔧 2. 테스트 종류별 구분

테스트 유형 대상 특징 예시 도구

단위 테스트 서비스, 도메인, 유틸리티 빠름, 독립성 높음 JUnit, Mockito
슬라이스 테스트 컨트롤러, 리포지토리 단위 일부 Bean만 로딩 @WebMvcTest, @DataJpaTest
통합 테스트 전체 API 흐름 실제 DB/빈/컨텍스트 포함 @SpringBootTest + MockMvc
시스템 테스트 외부 시스템 포함 실환경 유사, 느림 RestAssured, TestContainer

✅ 3. MockMvc 기반 통합 테스트

1️⃣ 기본 설정

@SpringBootTest
@AutoConfigureMockMvc
class UserApiTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void 사용자를_정상적으로_등록한다() throws Exception {
        String json = """
            {
              "name": "홍길동",
              "email": "hong@example.com",
              "password": "1234"
            }
            """;

        mockMvc.perform(post("/api/v1/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(json))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.success").value(true))
            .andDo(print());
    }
}

✅ 특징

  • Spring Context를 모두 띄우고, 실제 API 흐름을 검증
  • 빠르면서도 전체 흐름을 검증 가능
  • 단점: 필터/보안/에러 처리와 같은 일부 컴포넌트는 설정 필요

🧪 4. RestAssured 기반 API 테스트

RestAssured는 실제 HTTP 요청을 통해 서버를 테스트하는 데에 적합한 시스템 수준 테스트 도구입니다.

1️⃣ build.gradle 설정

testImplementation 'io.rest-assured:rest-assured:5.3.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

2️⃣ 테스트 예제

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class UserApiRestAssuredTest {

    @LocalServerPort
    int port;

    @Test
    @Order(1)
    void 회원가입_API_정상호출() {
        given()
            .port(port)
            .contentType(ContentType.JSON)
            .body("""
                {
                  "name": "이몽룡",
                  "email": "lee@test.com",
                  "password": "1234"
                }
            """)
        .when()
            .post("/api/v1/users")
        .then()
            .statusCode(200)
            .body("success", equalTo(true));
    }
}

✅ 특징

  • 실제 HTTP 요청을 통해 서버를 완전히 통합 테스트
  • Swagger 문서와 일치하는지 검증 가능
  • 보안/인증 헤더 추가, 파일 업로드 등 복합 요청 테스트에 유리

🐳 5. TestContainers – 외부 의존성까지 포함한 테스트

실제 DB(MySQL, Redis 등)를 Docker 컨테이너로 실행하여 통합 테스트를 강화하는 방식입니다.

예제: PostgreSQL 연동 테스트

@Testcontainers
@SpringBootTest
class PostgresIntegrationTest {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:13")
        .withDatabaseName("testdb")
        .withUsername("test")
        .withPassword("test");

    @DynamicPropertySource
    static void configureTestProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }

    @Test
    void DB_정상_연동_확인() {
        // 통합 테스트 실행
    }
}

✅ 특징

  • 실제 서비스 환경과 유사한 상태에서 테스트
  • 외부 API 모의(MockServer)와 함께 사용 가능
  • CI/CD 파이프라인에서도 유용

🧠 테스트 설계 전략 가이드

전략 설명

테스트 이름 한글로도 명확하게 작성 (ex. "회원가입 성공 시 200 OK")
정리된 구조 Given-When-Then 또는 Arrange-Act-Assert 구조 사용
테스트 격리 @Transactional 또는 TestContainer로 격리된 환경 유지
중복 제거 RestAssured 공통 설정은 Base 클래스로 분리
실패 테스트 포함 예외 상황, 400/403/404 응답도 반드시 포함

✅ 마무리 요약

항목 요약

MockMvc 빠르고 컨텍스트 포함 테스트, 주로 통합 테스트에 사용
RestAssured 실제 HTTP 요청 기반 테스트, 보안/문서 대응 용이
TestContainer 실제 DB/외부 시스템까지 포함하는 테스트 환경 구축
설계 원칙 빠른 테스트 → 통합 테스트 → 시스템 테스트 순서 설계

📌 다음 편 예고

Spring Boot 고급 시리즈 8편: API 응답 캐싱 전략 – Spring Cache와 Redis 실전 적용 가이드

 

728x90