테스트 코드를 짜면 빌드할 때 알아서 실행되고 잘 되면 ㅇㅋ, 안 되면 멈춤
테스트 코드를 짜는 이유 : 로컬 환경에서 짜놓은 코드가 운영 환경에서 잘 돌아가는지 빠르게 체크해보기 위해. (시스템의 주요 구성 요소들이 실제처럼 잘 협업하는지 검증하기 위해 작성한다.)
"배포된 상태에서 기능을 추가하면, 테스트 서버에서 확인 후 운영 서버로 간다. 운영 서버는 끌 수 없으니 로드 밸런서를 통해 트래픽을 옮긴다"
→ 실제로는:
- 운영 서버를 끄는 대신
- 로드 밸런서로 새 버전이 적용된 서버로 트래픽을 전환
- 문제가 없으면 점진적으로 전체 적용
- 문제가 생기면 빠르게 원래 버전으로 롤백 가능
package shop.mtcoding.blog.Integre;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import shop.mtcoding.blog.user.UserRequest;
// 가짜 세상을 만들어서 테스트하는 설정
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
// MockMvc 클래스가 IoC로드
@AutoConfigureMockMvc
public class UserControllerTest {
@Autowired // IoC 컨테이너에 ObjectMapper가 이미 있음 new 할 필요 없음.
private ObjectMapper om;
@Autowired
private MockMvc mvc;
@Test
public void join_test() throws Exception {
// given (가짜 데이터)
UserRequest.JoinDTO reqDTO = new UserRequest.JoinDTO();
reqDTO.setUsername("haha");
reqDTO.setPassword("1234");
reqDTO.setEmail("haha@nate.com");
String requestBody = om.writeValueAsString(reqDTO);
System.out.println(requestBody);
// when (테스트 실행) perform은 post요청 해주는 것
ResultActions actions = mvc.perform(
MockMvcRequestBuilders.post("/join").content(requestBody).contentType(MediaType.APPLICATION_JSON)
);
// eye (결과 눈으로 검증)
String responseBody = actions.andReturn().getResponse().getContentAsString();
System.out.println(responseBody);
// then (결과 코드로 검증)
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("성공"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.id").value(4));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.username").value("haha"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.email").value("haha@nate.com"));
}
}
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class UserControllerTest {
@SpringBootTest(webEnvironment = MOCK)
→ 진짜 서버를 띄우지 않고, 가짜 스프링 환경에서 테스트.
@AutoConfigureMockMvc
→
MockMvc
라는 테스트 도구를 사용할 수 있게 만들어줌.(실제 HTTP 요청 없이 컨트롤러 테스트 가능)
의존성 주입 (Autowired)
@Autowired
private ObjectMapper om;
ObjectMapper는 자바 객체를 JSON 문자열로 바꾸는 데 사용
@Autowired
private MockMvc mvc;
MockMvc
는 컨트롤러에 가짜 HTTP 요청을 보내는 도구.
- 진짜 브라우저가 요청 보내는 것처럼 테스트할 수 있음.
1. Given (테스트용 입력값 준비)
UserRequest.JoinDTO reqDTO = new UserRequest.JoinDTO();
reqDTO.setUsername("haha");
reqDTO.setPassword("1234");
reqDTO.setEmail("haha@nate.com");
String requestBody = om.writeValueAsString(reqDTO);
System.out.println(requestBody);

JoinDTO
는 회원가입에 필요한 데이터 클래스.
→
username
, password
, email
을 채워서 객체 생성.om.writeValueAsString()
→
reqDTO
객체를 JSON 문자열로 바꿔줌.예)
{"username":"haha", "password":"1234", "email":"haha@nate.com"}
2. When (HTTP 요청 실행)
ResultActions actions = mvc.perform(
MockMvcRequestBuilders.post("/join")
.content(requestBody)
.contentType(MediaType.APPLICATION_JSON)
);
MockMvcRequestBuilders.post("/join")
:
→ POST 방식으로
/join
요청을 만듦..content(requestBody)
→ JSON 형식의 요청 바디를 보냄.
.contentType(MediaType.APPLICATION_JSON)
→ Content-Type이 JSON이라고 알려줌.
actions
는 요청 결과를 담고 있음.
3. Eye (출력 확인)
String responseBody = actions.andReturn().getResponse().getContentAsString();
System.out.println(responseBody);

4. Then (결과 검증)
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("성공"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.id").value(4));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.username").value("haha"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.email").value("haha@nate.com"));
jsonPath()
는 JSON 응답의 특정 위치 값을 가져오는 도구
코드 | 설명 |
$.status | 응답 JSON에서 status 필드 값 → 200이어야 함 |
$.msg | 응답 JSON에서 msg 필드 값 → "성공"이어야 함 |
$.body.id | 회원가입한 사용자 ID → 4이어야 함 |
$.body.username | 회원 이름 → "haha" |
$.body.email | 회원 이메일 → "haha@nate.com" |
터트려 보기
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("성공"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.id").value(5)); // 5번으로 변경
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.username").value("haha"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.email").value("haha@nate.com"));

오류 메시지 요약
JSON path "$.body.id" expected:<5> but was:<4>
테스트에서 예상한 값: id == 5
실제 응답 값: id == 4
Share article