이번 포스트에서는 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() 같은 특정 콘텐츠를 위한 메서드 제공
- status()
- 응답을 검증하는 함수
'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 |
댓글