728x90
1. 통합테스트란
하나의 부품이 아니라, 전체가 잘 조립되어 돌아가는지 확인하는 테스트이다.
단위테스트가 메서드 하나에 대해서만 테스트 한다면 통합테스트는 요청-> Controller -> Service -> Repository -> 실제 DB까지의 로직을 한번에 검증합니다.
2. 왜 통합테스트가 필요한가?
통합테스트가 필요한 이유는 메서드들이 단위 테스트에서 정상적으로 작동하더라도 SQL 쿼리가 잘못되었거나 DB 제약조건때문에 실패하는 경우도 있고, 메서드끼리의 흐름이 정상적으로 이뤄지는지 확인해야하기 때문이다.
3.MockMvc
단위테스트에서도 테스트하기위한 메서드외에는 가짜 객체를 만드는 Mock을 사용했었는데,
통합테스트에서는 HTTP 요청을 보낼 수 있게 해주는 가짜요청하게 해주는 MockMvc라는것을 사용한다.
실제 Tomcat을 띄우는건 느리기 때문에 MockMvc는 스프링 내부에서 브라우저에서 요청이 온 것처럼 흉내를 내서 작동합니다.
빠르고, 헤더/쿠키/바디 조작이 쉬우며, 응답 결과를 상세하게 검증할 수 있습니다.
4. MockMvc 사용법
4-1. 기본 사용법
MockMvc는 기본적으로 요청, 검증, 로그 순으로 진행됩니다.
mockMvc.perform( 요청설정 )
.andExpect( 결과검증 )
.andDo( print() );
인증을 위한 정보또한 담을수 있고, 다양한 상황을 테스트 해볼수있습니다.
mockMvc.perform(
get("/articles")
.param("page", "1") // 쿼리 파라미터
.header("Authorization", "Bearer 토큰") // 인증 헤더
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(2));
5.perform(요청)
서버에 보낼 HTTP 요청을 조립하는 단계입니다.
아래 메서드들을 통해서 실제 HTTP 요청처럼 조립해서 쓸수있습니다.
.param("키", "값"): 쿼리 파라미터
.contentType(MediaType.APPLICATION_JSON): 보내는 데이터가 JSON임을 명시 (POST/PUT 필수).
.content("JSON 문자열"): 실제 전송할 데이터 본문 Body
.header("이름", "값"): 인증 토큰(Authorization) 등 헤더 추가.
.cookie(new Cookie("이름", "값")): 쿠키 추가.
5-1.경로 변수
Path 변수는 아래 형식처럼 사용할수있습니다.
mockMvc.perform(
get("/api/students/{id}", 1L)
)
5-2.Body
JSON으로 Body를 담아 보낼때는 """ 로 텍스트 블록을 활용하여 편하게 작성하도록 합시다.
mockMvc.perform(
post("/api/students")
.contentType(MediaType.APPLICATION_JSON) // 필수 JSON 타입 명시
.content("""
{
"name": "홍길동",
"age": 20
}
""")
)
6.andExpect 검증
andExpect는 이제 상태코드나 응답을 검증받을수있는 파트입니다.
status().isOk(): 200 OK
status().isCreated(): 201 Created (생성 성공)
status().isNoContent(): 204 No Content (삭제 성공)
status().isBadRequest(): 400 Bad Request (입력 오류)
status().isUnauthorized(): 401 Unauthorized (인증 실패)
content().string("문자열"): 응답이 단순 문자열일 때.
content().json(""" { ... } """): 응답 JSON 전체가 똑같은지 비교 (순서 무관).
jsonPath("$.필드명").value("값"): JSON의 특정 필드 값만 콕 집어서 비교.
여러 검증을 이어붙여서 한번에 검증하는것도 가능합니다.
.andExpect(status().isOk()) // 1. 상태 코드가 200인가?
.andExpect(content().contentType(MediaType.APPLICATION_JSON)) // 2. 응답이 JSON인가?
.andExpect(jsonPath("$.name").value("홍길동")) // 3. JSON의 name이 "홍길동"인가?
.andExpect(jsonPath("$.age").value(20)) // 4. JSON의 age가 20인가?
.andExpect(jsonPath("$.hobbies").isArray()) // 5. hobbies가 배열(리스트)인가?
728x90
'BackEnd > SpringBoot' 카테고리의 다른 글
| [SpringBoot] RabbitMQ (1) | 2026.01.09 |
|---|---|
| [SpringBoot] 동시요청에 대해 (0) | 2025.11.22 |
| [SpringBoot] QueryDSL (0) | 2025.09.30 |