반응형
실무 개발을 진행하면서 배포 Branch에 Merge Request를 하기 위해서는 필수적으로 Test 파일을 작성해야 했다.
많은 테스트 방법들을 배우고 있지만 그 중 API Controller 테스트 방법 중 하나인 mockMvc를 활용하게 되었고 이를 정리하려고 한다.
(개발자 단위 테스트, 통합 테스트 구별할 것..)
mockMvc 이란 무엇일까?
Controller 테스트를 위해 서버에 애플리케이션을 배포하지 않아도 MVC 패턴 및 동작을 테스트 할 수 있는 클래스이다.
말 그대로 mockMvc MVC 패턴의 mock 형태라고 이해하면 될 것 같다.
코드로 직접 확인해보자
일단 Test 진행할 컨트롤러는 다음과 같다.
@Slf4j
@RestController
public class APIController {
@GetMapping("/api/v1/food")
public Map<String, Object> retrieveFoodsOnAPI(@RequestParam(name = "criteria", required = false) String criteria) {
Map<String, Object> FoodsMap = new HashMap<>();
if ("회".equals(criteria)) {
List<Food> foodList = Arrays.asList(new Food("회", "광어", 200),
new Food("회", "우럭", 300),
new Food("회", "대방어", 500));
FoodsMap.put("body", foodList);
}
return FoodsMap;
}
}
이제 mockMvcTest 클래스를 작성을 통해 Controller Test를 작성해보자.
@Autowired로 MockMvc를 주입하려고 하면 bean을 찾을 수 없다라고 하는데 @AutoConfigureMockMvc 어노테이션을 클래스에 선언해준다.
@AutoConfigureMockMvc
@SpringBootTest
public class mockMvcTest {
private static final Cookie cookie = new Cookie("token", "test1234");
@Autowired
public MockMvc mockMvc;
@Test
@DisplayName("Get 회가 좋아요 - /api/v1/food")
public void FishFoodMockTest() throws Exception {
// 1) Parameter
MultiValueMap<String, String> param = new LinkedMultiValueMap<>();
param.add("criteria", "회");
// 2) mockMvc 실행
ResultActions resultActions = mockMvc.perform(get("/api/v1/food")
.params(param)
.cookie(cookie)
.contentType(MediaType.APPLICATION_JSON));
// 3) 결과
resultActions.andExpect(status().isOk())
.andExpect(jsonPath("$.body[0].name").value("광어"))
.andExpect(jsonPath("$.body[1].name").value("우럭"))
.andExpect(jsonPath("$.body[2].name").value("대방어"))
.andDo(print());
}
1) Parameter
Parameter 값은 MultiValueMap으로 설정할 수 있다. MultiValueMap의 구현체인 LinkedMultiValueMap으로 Paramter 값을 설정하였다.
MultiValueMap<String, String> param = new LinkedMultiValueMap<>();
param.add("criteria", "회");
물론. param 메서드를 통해 하나하나 매핑할 수도 있다.
2) mockMvc 실행
이제 위에 설정한 Paramter 값을 활용해서 개발한 API 테스트를 수행하는 mockMvc를 구현해보자.
ResultActions resultActions = mockMvc.perform(get("/api/v1/food")
.params(param)
.cookie(cookie)
.contentType(MediaType.APPLICATION_JSON));
- get("/api/v1/food") : GET 방식의 EndPoint가 /api/v1/food 인 API를 호출한다.
- params : 위에서 설정했던 paramter 값
- cookie : API 조회에 필요한 Cookie 또한 넣을 수 있다.
- contentType : xml, json 등 API 호출 결과 값 유형을 설정할 수 있다.
3) 결과
mockMvc가 수행한 결과값을 가지고 우리가 의도한대로 API 데이터가 반환하는지 확인한다.
resultActions.andExpect(status().isOk())
.andExpect(jsonPath("$.body[0].name").value("광어"))
.andExpect(jsonPath("$.body[1].name").value("우럭"))
.andExpect(jsonPath("$.body[2].name").value("대방어"))
.andDo(print());
- andExpect 메서드는 내가 예상하는 결과값 입력하여 mockMvc의 결과값과 비교한다.
- status().isOk() : 정상동작
- jsonPath(...) 결과 값에 대한 json 파싱 결과 비교
- andDo 메서드는 mockMvc를 수행하고 나서의 동작을 설정한다.
- print() mockMvc의 실행 Log을 확인 할 수 있다.
print()로 실행하는 mockMvc의 결과 이며
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/v1/food
Parameters = {criteria=[회]}
Headers = [Content-Type:"application/json;charset=UTF-8", Cookie:"token=test1234"]
Body = null
Session Attrs = {}
Handler:
Type = com.mspark.springstudy.controller.APIController
Method = com.mspark.springstudy.controller.APIController#retrieveFoodsOnAPI(String)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"application/json"]
Content type = application/json
Body = {"body":[{"kindValue":"회","name":"광어","kcal":200},{"kindValue":"회","name":"우럭","kcal":300},{"kindValue":"회","name":"대방어","kcal":500}]}
Forwarded URL = null
Redirected URL = null
Cookies = []
테스트 또한 에러 없이 잘 수행한 것을 확인 할 수 있다.
끝.
반응형
'개발 지식 > Spring Framework' 카테고리의 다른 글
[Test] MongoDB 단위 테스트(Unit Test) 작성해보기 (4) | 2022.06.06 |
---|---|
[Spring] SpringBoot + WebFlux + Kotlin + ReactiveMongo 프로젝트 생성 (1) | 2022.05.01 |
[thymeleaf] 기본 기능 정리 - 01 (0) | 2021.12.16 |
[JWT] Spring Boot 환경에서 JWT(Json Web Token)생성 하기 (0) | 2021.10.26 |
[Redis Session] Spring Boot에서 Redis Session 활용하기 - 04 (0) | 2021.09.26 |
댓글