skyho
skyho

Reputation: 1903

How to test getting parameters on the Rest service using the Post method

I'm trying to test getting parameters for processing a request using the Post method

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

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


…
        return null;
    }
}

variant 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);


    }
}

variant 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

In my project exceptions is handled thus:

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);
    }   

}

In methods, where necessary, I throw a specific exception...

.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'strListId' is not present]

Who knows what the error is. Please explain what you need to add here and why ?

Upvotes: 0

Views: 823

Answers (1)

babanin
babanin

Reputation: 3584

Let's take a look on declarations of postEntity:

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

As you can see, first argument is either URI or String with uriVariables, but second argument is always request entity.

In you first variant you put uri String as URI and then pass uriToEndpoint as request entity, pretending that it is request object. Correct solution will be:

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

Addressing your comments.

If server responded with HTTP 409, RestTemplate will throw exception with content of your ErrorResponseDto. You can catch RestClientResponseException and deserialize server response stored in exception. Something like this:

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

Upvotes: 1

Related Questions