Search code examples
javaspringrest-assured

Test using rest assured , body correctly sent but not read by application


I m using rest assured with latest version of java spring. I try to simulate call to authenticate with post method and json body (contentType is application/json) but when my request is intercepted by my java spring application, the body is empty.. and my authenticate methods throw a 401.. this behavior is correct. But the empty body isn't.

I can see with ngrep and some functions with rest assured that all request are correctly done.

When i use curl,postman or ajax from js client i don't have this problem

@EnableAutoConfiguration
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerImplTest {
    @Test
    public void testUserAuthenticateWitParams200() {

        Map<String, Object> jsonAsMap = new HashMap<>();
        jsonAsMap.put("email", "[email protected]");
        jsonAsMap.put("password", "groschat93**");

        given().log().all()
                .body(jsonAsMap)
                .contentType("application/json; charset=UTF-8").
        when()

.post(String.format("http://localhost:%s/api/users/authenticate", port))
                .peek().
        then()
                .statusCode(is(200));
    }
}

Here is the log from peek() function :

Request method: POST
Request URI:    http://localhost:53850/api/users/authenticate
Proxy:          <none>
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        Accept=*/* Content-Type=application/json; charset=UTF-8
Cookies:        <none>
Multiparts:     <none>
Body:
{
    "password": "groschat93**",
    "email": "[email protected]"
}

Here is the request from dev tool inside chrome

Request headers:

POST /api/users/authenticate HTTP/1.1
Host: back-spring.dev
Connection: keep-alive
Content-Length: 62
Origin: https://front.dev
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Content-type: application/json
Accept: */*
Referer: https://front.dev/
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7

Request Payload:

{"email":"[email protected]","password":"groschat93**"}

Solution

  • Problem was Tomcat and a useless semicolon in the header Content-Type. Tomcat wasn't able to read the content type with the semicolon with nothing following like charset. So when the request was read, server side, the default content type text/plain. RestAssured

    So i changed tomcat by undertow and i don't use rest assured anymore but WebTestClient. See codes and pom.xml. Source of this problem wasn't expected.

    @AutoConfigureWebTestClient
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
    @ContextConfiguration(
        classes={
                server_spring.Application.class,
                server_spring.config.WebSecurityConfig.class,
                server_spring.config.GlobalConfiguration.class,
                server_spring.config.MvcConfig.class,
                server_spring.config.WebConfig.class
        })
    public class UserControllerImplTest {
        @Autowired
        private WebTestClient webClient;
    
        @Test
        public void testWithAnotherMethod() {
            Map<String, String> jsonMap = new HashMap();
            jsonMap.put("email","[email protected]");
            jsonMap.put("password","groschat93**");
    
            webClient
                .post()
                .uri("/api/users/authenticate")
                .header("Origin","https://front.dev")
                .header("Referer","https://front.dev")
                .header("Host", "back-spring.dev")
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromObject(jsonMap))
                .exchange()
                .expectStatus()
                .isOk();
        }
    }
    

    My pom.xml

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>