< 스프링 부트 슬라이스 테스트 >
@WebMvcTest
- MockMvc 빈을 자동 설정 해준다. 그냥 가져와서 쓰면 됨.
- 웹 관련 빈만 등록해준다.
@MockMvc
- 스프링 MVC 테스트 핵심 클래스
- 웹 서버를 띄우지 않고도 요청을 처리하는 과정을 확인가능 → 컨트롤러 테스트용으로 자주 쓰임
테스트 내용
1. 입력값들을 전달하면 JSON 응답으로 201 값이 나오는지 확인
- Location 헤더에 생성된 이벤트를 조회할 수 있는 URI 담겨있는지 확인
- id는 DB에 들어갈 때 자동 생성된 값으로 나오는지 확인
@RestController
- @ResponseBody를 모든 메소드에 적용한 것과 동일
ResponseEntity를 사용하는 이유
- 응답코드, 헤더, 본문, 모두 다루기 편한 API
Location URI 만들기
- HATEOAS가 제공하는 linkTo(), methodOn() 사용
객체를 Json으로 변환
- ObjectMapper 사용
@MockBean
- Mockito를 사용해서 mock 객체를 만들고 빈으로 등록해줌 → WebMvcTest는 웹 관련 빈만 등록 해주기 때문에 repository와 같은 것들을 테스트 할 경우 MockBean으로 등록을 안해주면 NullPointerException이 날수있다!
- 주의! 기존 빈을 테스트용 빈이 대체 한다.
아래 예시를 살펴보자!
EventController.java
package me.whiteship.restapi.events;
import lombok.RequiredArgsConstructor;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.net.URI;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
@Controller
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_VALUE)
@RequiredArgsConstructor
public class EventController {
private final EventRepository eventRepository;
@PostMapping
public ResponseEntity createEvent(@RequestBody Event event) {
Event newEvent = eventRepository.save(event);
URI createdUri = linkTo(EventController.class).slash(newEvent.getId()).toUri();
return ResponseEntity.created(createdUri).body(event);
}
}
EventControllerTest.java
package me.whiteship.restapi.events;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
@WebMvcTest // 웹과 관련된 테스트만 하는 것 -> 슬라이스 테스트
public class EventControllerTest {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@MockBean
EventRepository eventRepository;
@Test
public void createEvent() throws Exception{
//given
Event event = Event.builder()
.name("Spring")
.description("REST API Development with Spring")
.beginEnrollmentDateTime(LocalDateTime.of(2018, 11, 23, 14, 21))
.closeEnrollmentDateTime(LocalDateTime.of(2018, 11, 25, 14, 21))
.beginEventDateTime(LocalDateTime.of(2018, 11, 26, 14, 21))
.basePrice(100)
.maxPrice(200)
.limitOfEnrollment(100)
.location("강남역 D2 스타텁 팩토리")
.build();
event.setId(10);
Mockito.when(eventRepository.save(event)).thenReturn(event);
mockMvc.perform(post("/api/events/") // post 요청을 보내고 -> perform을 하고 나면 응답이 옴
.contentType(MediaType.APPLICATION_JSON) // 요청에 json을 담아서 보내고 있다고 알려줌
.accept(MediaTypes.HAL_JSON) // 원하는 응답의 타입
.content(objectMapper.writeValueAsString(event))) // 객체를 json으로 변환
.andDo(print()) // 실제 응답이 어떻게 나왔는지 console에서 볼수 있음
.andExpect(status().isCreated())
.andExpect(jsonPath("id").exists());
//when
//then
}
}
'JAVA' 카테고리의 다른 글
String vs StringBuffer vs StringBuilder (0) | 2022.07.05 |
---|---|
spring boot 프로젝트 생성과 사용 이유 (0) | 2022.07.04 |
[JAVA] 지연로딩과 조회 성능 최적화 (0) | 2022.05.19 |
[JAVA] CRU API (0) | 2022.05.17 |
[JAVA] boolean @Getter (0) | 2022.03.24 |