ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Mock 테스트 시 given willReturn 이 null 을 반환하는 문제
    카테고리 없음 2023. 1. 27. 23:30

    mock test 중에 다음과 같이 null 에러가 발생하였다.

     

    TEST 코드와 Controller코드는 다음과 같다.

    @Test
    void signUpUser() throws Exception {
       //given
       StringloginId= "loginId@id.com";
       UserSignUpDto.Requestrequest= UserSignUpDto.Request.builder()
          .loginId(loginId)
          .nickname("nick")
          .password("1234")
          .phoneNumber("01012341234")
          .build();
    
    **given(userService.createUser(request)).willReturn(loginId);**
    
       //when
       //then
       mockMvc.perform(MockMvcRequestBuilders.post("/user")
             .contentType(MediaType.APPLICATION_JSON)
             .content(objectMapper.writeValueAsString(request)))
          .andExpect(status().isCreated())
          .andExpect(jsonPath("$.loginId").value(loginId));
    }
    

    Controller 코드

    @RequiredArgsConstructor
    @RestController
    public class UserController {
    
       private final UserService userService;
    
       @PostMapping("/user")
       public ResponseEntity<Map<String, String>> signUpUser(
          @RequestBody @Valid UserSignUpDto.Requestrequest, BindingResultbindingResult) {
    
          Map<String, String>response= new HashMap<>();
    
          if (bindingResult.hasErrors()) {
             for (FieldErrore:bindingResult.getFieldErrors()) {
    response.put(e.getField(),e.getDefaultMessage());
             }
             return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
          }
    
          **StringloginId= userService.createUser(request);**
    response.put("loginId",loginId);
    
          return new ResponseEntity<>(response, HttpStatus.CREATED);
       }
    }
    

     

    원인

    나는 스텁 메서드에서 기대하는 파라미터를 넘겼다고 생각했지만,

    디버깅을 돌려보니 mocking 된 service 에 스텁 메서드로 들어가는 Dto 인스턴스와 mockmvc.perform 할 때 생기는 Dto 인스턴스가 달랐다….

     

    해결

    mockito 에서 스텁 매서드의 파라미터를 비교할 때 equals()를 통해서 비교하므로 eqauls() 를 값을 비교하도록 오버라이딩하면 된다.

    여기서 Dto는 값만 비교하면 되는 클래스이므로 롬복의 @EqualsAndHashCode 어노테이션을 추가하여 해결하였다.

     

    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.EqualsAndHashCode;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    
    public class UserSignUpDto {
    
       @Builder
       @Getter
       @AllArgsConstructor
       @NoArgsConstructor
       @EqualsAndHashCode
       public static class Request {
          @NotNull
          @Email
          private String loginId;
    
          @NotNull
          private String nickname;
    
          @NotNull
          private String password;
    
          @NotNull
          private String phoneNumber;
       }
    }

     

Designed by Tistory.