[스프링부트] 37. 테스트 코드를 짜야 되는 이유

백하림's avatar
May 14, 2025
[스프링부트] 37. 테스트 코드를 짜야 되는 이유
💡
테스트 코드를 짜면 빌드할 때 알아서 실행되고 잘 되면 ㅇㅋ, 안 되면 멈춤
테스트 코드를 짜는 이유 : 로컬 환경에서 짜놓은 코드가 운영 환경에서 잘 돌아가는지 빠르게 체크해보기 위해. (시스템의 주요 구성 요소들이 실제처럼 잘 협업하는지 검증하기 위해 작성한다.)
💡
"배포된 상태에서 기능을 추가하면, 테스트 서버에서 확인 후 운영 서버로 간다. 운영 서버는 끌 수 없으니 로드 밸런서를 통해 트래픽을 옮긴다"
→ 실제로는:
  • 운영 서버를 끄는 대신
  • 로드 밸런서로 새 버전이 적용된 서버로 트래픽을 전환
  • 문제가 없으면 점진적으로 전체 적용
  • 문제가 생기면 빠르게 원래 버전으로 롤백 가능
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);
notion image
💡
  • 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);
notion image

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"));
notion image
오류 메시지 요약 JSON path "$.body.id" expected:<5> but was:<4> 테스트에서 예상한 값: id == 5 실제 응답 값: id == 4
 
Share article

harimmon