본 포스팅은 백기선님의 스프링 기반 REST API 개발 강좌를 수강하며 정리한 글입니다.
createEvent의 요청에 응답을 보댈 때 created 메소드 사용 -> 결과값이 uri가 나와야 함
즉 생성된 이벤트를 조회할 수 있는 uri를 담아서 보내줘야함.
이 uri를 편리하게 만들어주는 게 linkTo 메소드
URI createdUri = linkTo(EventController.class).slash("{id}").toUri();
실제 콘솔에서 어떤 요청과 어떤 응답을 받았는지 확인 가능
하나의 메소드가 아닌 eventController 클래스에 사용함으로써
value값을 설정해 eventController 클래스의 base url을 설정해줌!
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_VALUE)
객체를 JSON으로 변환하는 데 사용
@Autowired
ObjectMapper objectMapper;
// ... 생략...
mockMvc.perform(post("/api/events/")
//...
.content(objectMapper.writeValueAsString(event))) //json으로 줘야함 - ObjectMapper이용
//...
JUnit 테스트 코드 작성 중 오류 발생
java.lang.Exception: No runnable methods
올바른 클래스를 import 하지 않았기 때문!
//Before - error
import org.junit.jupiter.api.Test;
//After
import org.junit.Test;
cmd + shfit + T
테스트 생성
ctrl + R
이전 클래스 실행
ctrl + shift + R
실행
JpaRepository 상속 받아 EventRepository 생성
Enum은 기본 값이 ordinal
→ Enum에 정의된 값들이 순서대로 "정수값"으로 저장됨
→ 추후 정의된 값들의 "순서가 바뀌면" 데이터가 꼬임
➡️ String으로 바꿔주는 게 조아~~
EventControllerTests에서 @WebMvcTest
으로 빈을 주입해줬는데
이 어노테이션은 슬라이스 테스트로 웹용 빈만 등록해줌
즉, 레포지토리는 빈으로 등록 안해주기 때문에
Mockkito를 사용해 mock 객체를 만들고 빈으로 등록!
‼️주의
기존 빈을 테스트용 빈이 대체함
id 또는 입력받은 데이터로 계산해야 하는 값들은 입력을 받지 않아야 한다!
➡️ 여러 해결법이 있지만,
여기서는 DTO를 생성해서 해결
id랑 추후 계산해야 하는 값 빼고 dto 생성해주면 됨
이거 참 좋더라
ModelMapper의 map함수 한번이면 source model의 데이터를 destination model로 쫙 옮겨줌
단, 리플렉션 발생 (직접 코드로 옮기는거보다는 느림)
디펜던시 추가하기!
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.1</version>
</dependency>
슬라이싱 테스트였던 @WebMvcTest 제거
@SpringBootTest
@AutoConfigureMockMvc
추가
이후에 id, eventStatus, offline, free 값들 주어도 무시하고 있는지 확인!
//EventControllerTests.java
//..생략
@Test
public void createEvent_Bad_Request() throws Exception {
//...
mockMvc.perform(post("/api/events/")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaTypes.HAL_JSON)
.content(objectMapper.writeValueAsString(event)))
.andDo(print())
.andExpect(status().isBadRequest()) // 여기 수정!!
//입력값 외의 다른 값이 들어오면 에러 발생시키쟈!!!
;
}
Spring - 오브젝트 맵퍼 확장 기능
json → object : deserialization
object → json : serialization
spring.jackson.deserialization.fail-on-unknown-properties=true
➡️ 받을 수 없는 unknown -> id, free, offline 등등이 들어오면 bad request 띄워라!
Dto에 @NotNull, @NotEmpty, @Min, @Max
붙여주면 이를 사용해서 입력값을 바운딩할 때 에러를 확인함!
그 외 논리적 에러
요런거는 EventValidator 클래스 생성 후
검증하는 코드 작성!
커스텀 JSON Serializer 만들기!
extends JsonSerializer<T>
왜 만들어야 하냐?!
다 만들었다면 우리가 사용하고 있는 Object Mapper에 방금 만든 ErrorsSerializer을 등록해야 함
이걸 @JsonComponent 이 어노테이션이 해줌.
이제 object mapper는 Errors를 serialize할 때 얘를 사용함
비즈니스 로직 적용됐는지 응답메시지 확인
basePrice나 maxPrice가 0이면
아니면
free값은 false!
localtion이 null이거나 비어있으면
아니면
offline값은 true~!
테스트 코드를 리팩토링 하자!
디펜던시 추가
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>