문제상황
-
MockMvc를 이용하여 Controller를 테스트하고 있었다
-
createUser 메소드는 인자로 UserResponse(DTO) 객체를 받는다
-
UserResponse 내 int타입의 age변수의 값이 null로 들어오는 문제가 있었다
-
UserController.java
1@PostMapping("/user") 2public ResponseEntity<SuccessResponse<UserResponse>> createUser(UserRequest user) { 3 return SuccessResponse.get(201, userService.createUser(user)); 4}
-
UserControllerTest.java
1@Test 2void createUserTest() throws Exception { 3 // Given 4 User user = User.builder() 5 .id(1) 6 .name("hong") 7 // age의 값은 분명히 20 8 .age(20) 9 .hobby("swimming") 10 .build(); 11 UserRequest userReq = new UserRequest( 12 user.getName(), 13 user.getAge(), 14 user.getHobby()); 15 16 // When // Then 17 mockMvc.perform( 18 post("/user") 19 .contentType(MediaType.APPLICATION_JSON) 20 // userReq객체가 json string으로 정상적으로 변환된 것을 확인 21 .content(objectMapper.writeValueAsString(userReq))) 22 .andExpect(status().isCreated()) 23 .andExpect(jsonPath("$.content.name").value(user.getName())) 24 .andExpect(jsonPath("$.content.age").value(user.getAge())) 25 .andExpect(jsonPath("$.content.hobby").value(user.getHobby())) 26 .andExpect(jsonPath("$.serverDatetime").exists()) 27 .andDo(print()); 28}
-
Debug log
1...(생략) 2createUser(com.academy.board.dto.UserRequest): 3[Field error in object 'userRequest' on field 'age': rejected value [null]; 4...(생략)
-
UserRequest.java (DTO)
1@Getter 2@AllArgsConstructor 3public class UserRequest { 4 private String name; 5 private int age; 6 private String hobby; 7 8 public User toEntity() { 9 return User.builder() 10 .name(name) 11 .age(age) 12 .hobby(hobby) 13 .build(); 14 } 15}
해결방법
- UserRequest 클래스의 age의 타입을 int에서 Integer로 바꾸니까 해결되었다
- int는 변수의 타입으로, null을 허용하지 않고, Integer는 Wrapper class로, null을 허용한다는 특징을 가진다
- Spring에서 Wrapper클래스가 아닌 타입의 변수를 인자로 받는 행위를 금지시키는 것으로 보인다.