如何进行控制器层测试 feat 简单的代码示例

How to Controller Layer Test feat simple code example

代码:https://github.com/mijosan/test-practice/tree/master/mybatis

@RequiredArgsConstructor
@RestController
public class UserController {

  private final UserService userService;

  @PostMapping(value="/v1/user")
  public ResponseEntity<ResponseDto> postUser(@RequestBody UserSaveRequestDto userSaveRequestDto) {
      Long userId = userService.insertUser(userSaveRequestDto);

      return CommonUtil.getResponseEntity(UserResponseDto.builder()
                                                              .userId(userId)
                                                              .build()
                                                              , HttpStatus.OK
                                                              , "회원 등록 완료");
  }

}

这是我的测试代码

@WebMvcTest
public class UserControllerTest {

  @Autowired
  MockMvc mockMvc;

  @Autowired
  ObjectMapper objectMapper;

  @MockBean
  UserService userService;

  UserSaveRequestDto userSaveRequestDto;

  @BeforeEach
  void setUp() {
      userSaveRequestDto = UserSaveRequestDto.builder()
          .userName("test")
          .userPhoneNumber("01026137832")
          .build();
  } 

  @DisplayName("MockMvc를 이용한 postUser slice 테스트")
  @Test
  public void postUserTest() throws Exception {
      // given
      given(userService.insertUser(userSaveRequestDto)).willReturn(1L);
      String content = objectMapper.writeValueAsString(userSaveRequestDto);

      // when
      MvcResult mvcResult = mockMvc.perform(post("/v1/user")
                      .contentType(MediaType.APPLICATION_JSON)
                      .content(content))
                          .andExpect(status().isOk())
                          .andReturn();
    
      // then
      String result = mvcResult.getResponse().getContentAsString();

      System.out.println(result);
  }

}

并且我收到异常“java.lang.AssertionError:预期状态:<200> 但为:<500>”

但是,如果你大摇大摆地测试它,它会很好用。

原因在哪里?

如果将测试代码修改为

...
.content(content))
    .andDo(result -> {
        result.getResolvedException().printStackTrace();
    })
    .andExpect(status().isOk())
...

你会在日志中找到

org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class com.example.mybatis.dto.ResponseDto
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:220)
    at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:219)
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
....

500 的原因是控制器无法序列化您的 ResponseDto。您需要在 ResponseDto 上添加 lombok.Getter