java - org.springframework.web.client.HttpClientErrorException : 400 null

标签 java spring rest unit-testing junit

我为 FilterDataController 编写了测试。但是我在执行测试期间出现以下错误。当我手动发送 GET 请求时,我收到了正确的 JSON。

org.springframework.web.client.HttpClientErrorException: 400 null

    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:667)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:620)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580)
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:312)
    at com.company.integration.tests.rest.StatisticEndpointTest.checkFilterDataControllerInvalidBodyResponse(StatisticEndpointTest.java:284)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)

我的测试:

@Test
public void checkFilterDataControllerInvalidBodyResponse() {
    String servicePath = getBaseUrl() + "/statistics/filters?startDate={startDate}&endDate={endDate}";
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> response = restTemplate.getForEntity(servicePath, String.class, "", "");
    assertThat(response, notNullValue());
    assertThat(response.getStatusCode(), equalTo(HttpStatus.BAD_REQUEST));
}

过滤数据 Controller

/**
 * controller which provides possible filters data for UI
 */

@RestController
@RequestMapping("/statistics")
@Api(value = "/statistics",description = "API for possible filters data")
public class FilterDataController {

    public static final String DATE_FORMAT = "yyyy-MM-dd";

    @Autowired
    private FilterDataProvider filterDataProvider;

    @ApiOperation(value = "Get possible filter data",response = ResponseEntity.class)
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "The response data should be used as bricks in all future statistics requests"),
            @ApiResponse(code = 204, message = "Data not found. Select another timeframe")})
    @RequestMapping(path = "/filters", method = RequestMethod.GET)
    public ResponseEntity<Object> getPossibleFilterData(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern=DATE_FORMAT) final Date startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern=DATE_FORMAT) final Date endDate) {
        if (startDate == null || endDate == null){
             throw new ValueNotAllowedException("Dates mustn't be null");
        }
        if (endDate.compareTo(startDate) == -1){
            throw new ValueNotAllowedException("End date should be after or equal start date");
        }
        else {
            Date newEndDate = endDate;
            if (startDate.equals(endDate)){
                newEndDate = new Date(endDate.getTime() + TimeUnit.DAYS.toMillis(1) - 1);
            }
            List<String> possibleMails =  Lists.newArrayList(filterDataProvider.getPossibleMails(startDate, newEndDate));

            <...>

            return new ResponseEntity<>(new FilterResponse(possibleMails, possibleSubjects, possibleCountries, possibleSizes, possibleStates),HttpStatus.OK);
        }
    }

    @ExceptionHandler(ValueNotAllowedException.class)
    void handleBadRequests(HttpServletResponse response, ValueNotAllowedException ex) throws IOException {
        response.sendError(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
    }
}

postman 的回复:

获取 http://localhost:8888/statistics/filters?startDate=&endDate=

{
  "timestamp": 1476690591750,
  "status": 400,
  "error": "Bad Request",
  "exception": "com.services.exceptions.ValueNotAllowedException",
  "message": "Dates mustn't be null",
  "path": "/statistics/filters"
}

我发送到 getForEntity 的参数是正确的,因为当我发送相同的参数但日期正确时 - 它运行良好。

最佳答案

您应该使用 TestRestTemplate 而不是 RestTemplate

Class TestRestTemplate

适用于集成测试的 RestTemplate 的便捷替代品。它们是容错的,并且可以选择携带基本身份验证 header 。如果 Apache Http Client 4.3.2 或更高版本可用(推荐),它将用作客户端,并且默认配置为忽略 cookie 和重定向。

改变

@Test
public void checkFilterDataControllerInvalidBodyResponse() {
    String servicePath = getBaseUrl() + "/statistics/filters?startDate={startDate}&endDate={endDate}";
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> response = restTemplate.getForEntity(servicePath, String.class, "", "");
    assertThat(response, notNullValue());
    assertThat(response.getStatusCode(), equalTo(HttpStatus.BAD_REQUEST));
}

@Test
public void checkFilterDataControllerInvalidBodyResponse() {
    String servicePath = getBaseUrl() + "/statistics/filters?startDate={startDate}&endDate={endDate}";
    TestRestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> response = restTemplate.getForEntity(servicePath, String.class, "", "");
    assertThat(response, notNullValue());
    assertThat(response.getStatusCode(), equalTo(HttpStatus.BAD_REQUEST));
}

关于java - org.springframework.web.client.HttpClientErrorException : 400 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40081397/

相关文章:

java.lang.OutOfMemoryError : PermGen space: java reflection 错误

java - 在 MyBatis 中返回一个列表<MyClass>

Spring 电子邮件 : Must issue a STARTTLS command first

java - Hibernate 4 - 调用 DAO 和初始化 sessionFactory bean

jQuery - 发送跨域 PUT/DELETE 请求

java - 如何解决 glassfish 上的 Web 服务应用程序中的 "HTTP Status 500 - Internal Server Error"问题?

Eclipse - 没有 Java (JRE)/(JDK) ...没有虚拟机

java - Spring可以根据类(名称)在上下文中添加一个bean并注入(inject)吗?

java - 由于在 REST 中使用 HATEOAS 而导致循环依赖

java - 我们可以对 REST 服务进行 UDP 调用吗