본문 바로가기
Spring

Spring - JUnit+Mock 기반 스프링 단위테스트

by icblue21 2022. 11. 21.
728x90

이번 포스트에서는 JUnit과 Mock을 기반으로 스프링에서 단위 테스트를 하는 방법에 대해 정리해보겠습니다.

Mock

가장 먼저 Mock에 대해 알아보겠습니다. Mock은 테스트를 위한 가짜 객체를 말합니다. 테스트를 할 때 객체가 필요하면 객체를 만들어야하는데 실제 객체를 만들기 위해서는 비용/시간/의존성문제가 걸쳐져 있습니다. 때문에 실제 객체를 구현하기 어려울 경우 Mock이라는 가짜 객체를 이용하여 테스트를 진행합니다.

Mokito

Mokito는 개발자가 동작을 직접 제어할 수 있는 가짜 객체를 지원하는 테스트 프레임워크입니다.

[스프링 객체 의존도 그림]


[Mock 객체를 이용한 단위 테스트]

보통 스프링으로 웹 어플리케이션을 개발하면 여러 객체들의 의존성이 생기는데, 이러한 의존성은 단위 테스트를 작성하기 어렵게 만듭니다. Mokito에서는 가짜 객체를 주입시켜 이러한 의존성 문제를 해결 할 수 있는 라이브러리를 제공합니다. 즉, Mokito를 이용하면 가짜 객체(Mock)에 원하는 결과를 임의로 작성하여 단위 테스트를 진행할 수 있습니다. 하지만 가짜 객체(Mock)를 이용하지 않아도 테스트를 진행할 수 있다면 만들지 않는 것이 좋습니다.

JUnit

JUnit이란 자바 프로그래밍 언어용 유닛 테스트 프레임워크입니다.
테스트 결과는 Test클래스로 개발자에게 테스트 방법 및 클래스 History를 공유할 수 있습니다.
assert 메소드로 테스트 케이스의 수행 결과를 판별하며 어노테이션을 이용하여 간편하게 사용할 수 있습니다.

Mockito+JUnit

Mockito도 테스팅 프레임워크이기 때문에 JUnit과 결합하기 위해서 다음과 같은 작업이 필요합니다.

  • @RunWith(MokitoJUnitRunner.class) : JUnit4에서 Mockito를 활용하기 위한 어노테이션
  • @ExtendWith(MokitoExtension.class) : JUnit5에서 Mockitof를 활용하기 위한 어노테이션 Spring Boot 2.2.0부터 사용 가능

Mokito 사용법

만약 MemberController에 대한 단위 테스트를 진행하고자 할 때, MemberService를 가지고 있다면 @Mock 어노테이션을 통해 가짜 MemberService를 만듭니다. 그리고 @InjectMock를 통해 MemberController에 주입 합니다.

@RunWith(MockitoJUnitRunner.class) // JUnit4에서 Mockito를 활용하기 위한 어노테이션
public class LoginRestControllerMockito {

    @InjectMocks
    private LoginRestController loginRestController;

    @Mock
    private MemberService memberService;
    

    private MockMvc mockMvc; // request 수행해주는 mock 객체


    @Before
    public void before() {
        mockMvc = MockMvcBuilders.standaloneSetup(loginRestController).build();
    }



    @DisplayName("로그인 테스트")
    @Test
    public void 로그인_테스트() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.post("/login")
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .param("uId", "a")
                        .param("uPw", "a12345"))
                .andExpect(status().isBadRequest())
                .andDo(print());
    }

}

Spring에서 MockMVC

MockMVC는 스프링에서 MVC테스트를 하기 위한 방법을 논의하여 스프링 테스트 모듈을 스프링 프레임워크에 더한 것으로, 이미 스프링에서 관리하고 있는 빈을 @Autowired받아 스프링 컨텍스트 환경으로 테스트할 수 있게 도와주는 라이브러리 입니다.

@RunWith(SpringJunit4ClassRunner.class) // SpringJunit4ClassRunner.class는 spring-test에서 제공하는 단위테스트를 위한 클래스 러너
@ContextConfiguration(classes = {WebAppConfig.class, DispatcherServletConfig.class})
@WebAppConfiguration // WebApplicationContext 생성할 수 있도록 하는 어노테이션
public class LoginRestControllerTest {

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private MemberDAO memberDAO;

    private MockMvc mockMvc; // request 수행해주는 mock 객체

		...

}

MockMVC에는 다양한 메소드가 존재합니다.

  • perform()
    • 요청을 전송하는 함수
    • 결과로 ResultActions객체 반환
    • ResultActions객체는 리턴 값을 검증하고 확인할 수 있는 andExpect()메소드 제공
  • get()/post()/put()/patch()/delete()
    • HTTP 메소드 결정
    • 인자로 URI 경로 전달
  • param()
    • 키 = 값 형태의 파라미터를 전달할 수 있음
    • 값이 여러개일 경우 param()메소드 체이닝해서 작성 가능 또는 params() 사용 가능
  • andDo(print())
    • 요청/응답 전체 메시지 확인 함수
  • andExcept()
    • 응답을 검증하는 함수
      • status()
        • isOk(): 202
        • isBadRequest(): 400
        • isNotFound(): 404
        • isMethodNotAllowed(): 405
        • isConflict(): 409
        • isUnsupportedMediaType(): 415
        • isInternalServerError(): 500
        • is(int status): status 상태 코드
      • header()
        • 응답 헤더 상태 검증
      • cookie()
        • 쿠키 상태 검증
      • view()
        • 반환하는 뷰 이름을 검증
      • forwarededUrl()
        • 이동 대상 경로 검증
        • 패턴으로 검증할 때는 forwardedUrlPattern() 사용
      • redirectedUrl()
        • 리다이렉트 대상 경로 또는 URL 검증
        • 패턴으로 검증시에는 redirectedUrlPattern() 사용
      • model()
        • 컨트롤러에서 저장한 모델들 정보 검증
      • content()
        • 응답에 대한 정보 검증
        • jsonPath()나 xpath() 같은 특정 콘텐츠를 위한 메서드 제공

'Spring' 카테고리의 다른 글

Spring - Log4j2  (0) 2022.11.21
Spring - ExceptionHandler  (0) 2022.11.21
Spring - ResponseEntity, RequestEntity  (0) 2022.11.21
Spring - @RestController  (0) 2022.11.21
Spring - Rest API  (0) 2022.11.21

댓글