【问题标题】:How to test getting parameters on the Rest service using the Post method如何使用 Post 方法测试在 Rest 服务上获取参数
【发布时间】:2020-08-21 19:25:10
【问题描述】:

我正在尝试使用 Post 方法测试获取用于处理请求的参数

@RestController
@RequestMapping("api")
public class InnerRestController {

…
    @PostMapping("createList")
    public ItemListId createList(@RequestParam String strListId,
@RequestParam String strDate) {


…
        return null;
    }
}
  • 测试方法

变体 1

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class InnerRestControllerTest {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void innerCreatePublishList() {

        String url = "http://localhost:" + this.port;

        String uri = "/api/createList";

        String listStr = "kl";

        String strDate = "10:21";

        URI uriToEndpoint = UriComponentsBuilder
                .fromHttpUrl(url)
                .path(uri)
                .queryParam("strListId", listStr)
                .queryParam("strDate ", strDate)
                .build()
                .encode()
                .toUri();

        ResponseEntity< ItemListId > listIdResponseEntity =
                restTemplate.postForEntity(uri, uriToEndpoint, ItemListId.class);


    }
}

变体 2

@Test
void createList() {

        String uri = "/api/createList";

        String listStr = "kl";

        String strDate = "10:21";

    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(uri)
                .queryParam("strListId", listStr)
                .queryParam("strDate ", strDate);

    Map<String, String> map = new HashMap<>();

    map.put("strListId", listStr);//request parameters
    map.put("strDate", strDate);


    ResponseEntity< ItemListId > listIdResponseEntity =
            restTemplate.postForEntity(uri, map, ItemListId.class);


}

Update_1

在我的项目中,异常是这样处理的:

  • dto
public final class ErrorResponseDto {

    private  String errorMsg;

    private  int status;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    LocalDateTime timestamp;

...
  • 处理程序
@RestControllerAdvice
public class ExceptionAdviceHandler {

    @ExceptionHandler(value = PublishListException.class)
    public ResponseEntity<ErrorResponseDto> handleGenericPublishListDublicateException(PublishListException e) {

        ErrorResponseDto error = new ErrorResponseDto(e.getMessage());
        error.setTimestamp(LocalDateTime.now());
        error.setStatus((HttpStatus.CONFLICT.value()));

        return new ResponseEntity<>(error, HttpStatus.CONFLICT);
    }   

}

在方法中,如有必要,我会抛出一个特定的异常......

.w.s.m.s.DefaultHandlerExceptionResolver:已解决 [org.springframework.web.bind.MissingServletRequestParameterException: 必需的字符串参数“strListId”不存在]

谁知道错误是什么。请说明您需要在此处添加的内容以及原因?

【问题讨论】:

    标签: java spring-boot rest integration-testing spring-resttemplate


    【解决方案1】:

    让我们来看看postEntitydeclarations

    postForEntity(URI url, Object request, Class<T> responseType)
    ...
    postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
    

    如您所见,第一个参数是URIString with uriVariables,但第二个参数始终是请求实体。

    在您的第一个变体中,您将 uri 字符串作为 URI,然后将 uriToEndpoint 作为请求实体传递,假装它是请求对象。正确的解决方案是:

    ResponseEntity<ItemListId> listIdResponseEntity =
                    restTemplate.postForEntity(uriToEndpoint, null, ItemListId.class);
    

    解决您的 cmets。

    如果服务器以 HTTP 409 响应,RestTemplate 将抛出您的 ErrorResponseDto 内容的异常。您可以捕获RestClientResponseException 并反序列化存储在异常中的服务器响应。像这样的:

    try {
      ResponseEntity<ItemListId> listIdResponseEntity =
                    restTemplate.postForEntity(uriToEndpoint, null, 
      ItemListId.class);
      
      ...
    } catch(RestClientResponseException e) {
      byte[] errorResponseDtoByteArray  = e.getResponseBodyAsByteArray();
      
      // Deserialize byte[] array using Jackson
    }
    

    【讨论】:

    • 谢谢伊万·巴巴宁。我已经收到了对端点 Rest-service 的请求。但是,当 有抛出异常时,则 excetpionHandler 必须回答 - { "errorMsg": "PublishList with parameter values such as' key and id ' is already installed.", "status": 409, " timestamp": "2020-08-21 11:08:43" } ,但我只得到 - 状态码。我必须添加什么,并且我可以得到 - {“errorMsg”:“带有参数值的PublishList,例如'key andid'已经安装。”,“status”:409,“timestamp”:“ 2020-08-21 11:08:43" }
    • 这种类型的 json 的容器(在后端)有一个不同的类型 - ErrorResponseDto。据我了解,您需要返回泛型类型?
    • Ivan Babanin,测试方法中的异常捕获,不适合我的情况(见上文,我添加了信息...),会出现异常,它会被拦截器捕获。在测试方法中,我只能得到 json 格式的现成答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多