Can not get HAL format in Spring Boot MVC unit test
Asked Answered
C

1

12

I am trying the Spring HATEOAS with Spring Boot. And I wrote a unit test with rest assured:

given().standaloneSetup(new GreetingApi())
        .accept("application/hal+json;charset=UTF-8")
        .when()
        .get("/greeting")
        .prettyPeek()
        .then().statusCode(200)
        .body("content", equalTo("Hello, World"))
        .body("_links.self.href", endsWith("/greeting?name=World"));

The test return response like this:

Content-Type: application/hal+json;charset=UTF-8

{
    "content": "Hello, World",
    "links": [
        {
            "rel": "self",
            "href": "http://localhost/greeting?name=World"
        }
    ]
}

But actually the response get like this when I run the whole Spring Boot Application:

HTTP/1.1 200 
Content-Type: application/hal+json;charset=UTF-8
Date: Wed, 24 May 2017 15:28:39 GMT
Transfer-Encoding: chunked

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/greeting?name=World"
        }
    },
    "content": "Hello, World"
}

So there must be some method to configure the response for HATEOAS, but I didn't find it.

Hope someone who is familiar about this can help me.

The whole repository is here.

Chromogenic answered 24/5, 2017 at 15:34 Comment(0)
S
5

The problem is because you are using standaloneSetup() method. Which means you do construct all the Spring MVC programmatically, and your test is not aware about all the Spring Boot 'magic'. Therefore this test have minimal Spring MVC infrastructure, which do not know how to work with HATEOAS.

The possible solution is to use WebApplicationContext prepared for by Spring Boot:

@RunWith(SpringRunner.class)
@SpringBootTest
public class GreetingApiTest {

    @Autowired
    private WebApplicationContext context;

    @Test
    public void should_get_a_content_with_self_link() throws Exception {
        given()
            .webAppContextSetup(context)
            .accept("application/hal+json;charset=UTF-8")
        .when()
            .get("/greeting")
            .prettyPeek()
        .then()
            .statusCode(200)
            .body("content", equalTo("Hello, World"))
            .body("_links.self.href", endsWith("/greeting?name=World"));
    }
}
So answered 30/5, 2017 at 9:36 Comment(7)
Yeah, you are right. I know the integration test (with annotation SpringBootTest) do work, while I really want to use the standalone way to accelerate the test speed. So my point is " there must be some method to configure the response for HATEOAS". I am looking for the right config method.Chromogenic
But maybe the standalone way for test is not the best practice for Spring Boot. If you think SpringBootTest is the right way, can you give me more information about that? Thanks.Chromogenic
@aisensiy, if you want create more isolated test for GreetingApi controller, you can use another nice feature from Spring Boot Test module called WebMvcTest. You can annotate your test class like this @WebMvcTest(GreetingApi.class) In this case Spring Boot will apply only configuration relevant to MVC tests, and even more you can specify concrete controller class.So
@aisensiy, could you elaborate more on your complains about tests speed?So
I tried the WebMvcTest way, it works. But I still think that manually control the create of a controller and give the dependency it want is a good way for unit test... Feel confusing about that.Chromogenic
The speed may not be the key problem here, because this is just a very small application with only a few api. But I do see some big application with a lot api run test very slow by Integration Test. But maybe the best solution is use the WebMvcTest. I think the standalone way is also use MockMvc but without right configuration...Chromogenic
Could you please reorganize the @WebMvcTest part and give some more information links about that. I think this is the solution for me in this situation.Thank you very much.Chromogenic

© 2022 - 2024 — McMap. All rights reserved.