11.18 TIL - 통합 테스트

이서준·2025년 11월 18일

TIL

목록 보기
2/24

그전에 알아야 할 것

Spring Test

  • 스프링 프레임워크에서 제공하는 통합 테스트 및 스프링 MVC 통합 테스트 지원

Junit

  • 단위 테스트 도구
  • 단정문으로 테스트 케이스의 수행 결과를 판단 assetEquals(예상값, 실제값)

Mock

  • 실제 객체를 만들기엔 비용과 시간이 많이 들거나 의존성이 길게 걸쳐져있어 제대로 구현하기 어려울 경우 가짜 객체를 만들어 사용
    -> 가짜 객체

단위 테스트

  • 하나의 기능 또는 메서드를 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트
  • 특징
    • 빠름
    • 문제 원인 파악이 쉬움
    • Mock 사용이 많음
  • 한계
    • 실제 환경과 다름
    • 여러 컴포넌트가 연결되었을 때 발생하는 문제는 탐지 불가

테스트 코드 작성 규칙

  • 1개의 단위 테스트를 3가지 단계로 나누어 처리하는 패턴
  • given(준비) : 어떠한 데이터가 준비되었을 때
  • when(실행) : 어떠한 메서드를 실행하면
  • then(검증) : 어떠한 결과가 나와야 함

통합 테스트

  • 스프링 어플리케이션의 여러 계층(Controller, Service, Repository)을 실제처럼 묶어서 테스트 하는 것
  • 스프링 컨텍스트를 실제로 띄우고 DB, Bean 주입까지 구성한 상태에서 전체 기능 흐름을 테스트

통합 테스트 특징

  1. 실제 환경과 매우 유사
    a. 어플리케이션 전체 빈이 실제로 올라감
    b. Mock이 아니라 Repository와 Service 사용 가능
  2. 단점
    a. 느림 -> SpringBoot가 실제로 기동되어서 시간이 오래 걸림
    b. 문제 원인 파악이 어려울 수 있음 -> 많은 계층이 있어 어디서 오류 났는지 찾기 복잡할 수 있음

MockMvc ResultAction

1. .perform()

  • MockMvc를 사용하여 HTTP 요청을 실행
  • post(), get() : HTTP 메서드를 결정
  • contentType() : 요청의 Content-Type 설정
  • param(), params() : 쿼리 파라미터 추가
//예시
mockMvc.perform(get("/users"))
				.param("pageNumber", 0)
				.param("pageSize", 5)
				.andExpect(status().isOk());

2. .andExpect(ResultMatcher)

  • 응답값과 기대값을 검증하는 메서드
  • status().is.Ok() → HTTP 상태 코드 검증
  • jsonPath(”$.필드”).value(”값”)
//예시
mockMvc.perform(post("/login"))
    				.andExpect(status().isOk())
    				.andExpect(jsonPath("$.content.email").value("seo@jun.com"));

3. .andDo(ResultHandler)

  • 결과를 출력하거나 로그 남기고 싶을 때 사용
  • print()
//예시
mockMvc.perform(post("/login"))
           .andDo(print())
           .andExpect(status().isOk());

4. .andReturn()

  • 요청 수행 후 MvcResult 객체를 얻고 싶을 때 사용
  • 세션을 확인한다거나, 응답 Json을 직접 꺼낼 때 필요함
//예시
MvcResult result = mockMvc.perform(post("/login"))
           .andExpect(status().isOk())
           .andReturn();
    
String json = result.getResponse().getContentAsString();
MockHttpSession session = (MockHttpSession) result.getRequest().getSession();

실험 코드

로그인 테스트

@DisplayName(value = "로그인 및 로그아웃 테스트")
@Test
void loginTest() throws Exception {

	//given
	//1. 회원가입 먼저 진행
	User user = new User("seo@jun.com", "이서준", encoder.encode("test"));
	userRepository.save(user);

	//2. 로그인 요청 바디
	String json = "{ \"email\":\"seo@jun.com\", \"password\":\"test\"}\"";

	//when 로그인 수행
	MvcResult result = mockMvc.perform(post("/login")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(json))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.content.id").value(1L))
                .andExpect(jsonPath("$.content.email").value("seo@jun.com"))
                .andReturn();

	//then 세션 확인
	MockHttpSession session = (MockHttpSession) result.getRequest().getSession();

	Assertions.assertNotNull(session);  //세션 있나요
	SessionUser sessionUser = (SessionUser) session.getAttribute("loginUser");
	Assertions.assertNotNull(sessionUser);  //DTO 있나요

	//1. 이메일 확인
	assertEquals("seo@jun.com", sessionUser.getEmail());
}
  • perform() : MockMvc를 사용하여 HTTP 요청을 실행
  • .andExpect(status().isOk()) : 상태 코드 OK 확인 틀리면 테스트 실패
  • .andExpect(jsonPath("$.content.id").value(1L)) : 응답 바디에 루트-> content->id의 값이 1이 아니면 테스트 실패
  • Assertions.assertNotNull(sessionUser) : sessionUser가 nul이면 테스트 실패 null이 아니면 테스트 통과
profile
Allons-y

0개의 댓글