Validate LocalDate in JSON response with Spring MockMVC
Asked Answered
A

6

6

I'm trying to validate a LocalDate object in a JSON result returned by a Spring MVC webservice but I can't figure out how.

At the moment I always run into assertion errors like the following one:

java.lang.AssertionError: JSON path "$[0].startDate" Expected: is <2017-01-01> but: was <[2017,1,1]>

The important part of my test is posted below. Any ideas how to fix the test to pass?

import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;

public class WebserviceTest {

    @Mock
    private Service service;

    @InjectMocks
    private Webservice webservice;

    private MockMvc mockMvc;

    @Before
    public void before() {
        mockMvc = standaloneSetup(webservice).build();
    }

    @Test
    public void testLocalDate() throws Exception {
        // prepare service mock to return a valid result (left out)

        mockMvc.perform(get("/data/2017")).andExpect(status().isOk())
            .andExpect(jsonPath("$[0].startDate", is(LocalDate.of(2017, 1, 1))));
    }
}

The webservice returns a list of view objects looking like this:

public class ViewObject {

    @JsonProperty
    private LocalDate startDate;
}

[edit]

Another try was

.andExpect(jsonPath("$[0].startDate", is(new int[] { 2017, 1, 1 })))

which resulted in

java.lang.AssertionError: JSON path "$[0].startDate" Expected: is [<2017>, <1>, <1>] but: was <[2017,1,1]>

[edit 2] The returned startDate object seems to be of type: net.minidev.json.JSONArray

Abrasion answered 9/10, 2017 at 14:51 Comment(0)
A
4

This is the way to go. Thanks to 'Amit K Bist' to point me in the right direction

...
.andExpect(jsonPath("$[0].startDate[0]", is(2017)))
.andExpect(jsonPath("$[0].startDate[1]", is(1)))
.andExpect(jsonPath("$[0].startDate[2]", is(1)))
Abrasion answered 10/10, 2017 at 6:49 Comment(0)
W
3

This should pass:

.andExpect(jsonPath("$[0].startDate", is(LocalDate.of(2017, 1, 1).toString())));
Wellman answered 27/5, 2020 at 22:20 Comment(1)
Adding toString worked for me.Mountain
D
1

LocalDate in JSON response will be like "startDate":

"startDate": {
    "year": 2017,
    "month": "JANUARY",
    "dayOfMonth": 1,
    "dayOfWeek": "SUNDAY",
    "era": "CE",
    "dayOfYear": 1,
    "leapYear": false,
    "monthValue": 1,
    "chronology": {
        "id": "ISO",
        "calendarType": "iso8601"
    }
}

So, you should check each attribute like below:

.andExpect(jsonPath("$[0].startDate.year", is(2017)))
                .andExpect(jsonPath("$[0].startDate.dayOfMonth", is(1)))
                .andExpect(jsonPath("$[0].startDate.dayOfYear", is(1)))
Dominic answered 10/10, 2017 at 0:23 Comment(2)
I did not realize that you are using jsr310 so above will work only for non-jsr310 localdateDominic
Sorry: java.lang.AssertionError: No value at JSON path "$[0].startDate.year", exception: Expected to find an object with property ['year'] in path $[0]['startDate'] but found 'net.minidev.json.JSONArray'. This is not a json object according to the JsonProvider: 'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'.Abrasion
B
0

Because it expects a list of values, you can use it like that.

.andExpect(jsonPath("$[0].startDate", is(List.of(2022, 1, 1))))
Baseboard answered 17/8, 2022 at 12:32 Comment(0)
P
0

Based on the answer of GreenTurle, but with a different falvour:

        .andExpect(jsonPath("$[0].startDate[0]").value(2017))
        .andExpect(jsonPath("$[0].startDate[1]").value(1))
        .andExpect(jsonPath("$[0].startDate[2]").value(1))

You can use .value() to compare the parts of the date instead of is() function.

Panic answered 13/11, 2023 at 12:31 Comment(0)
I
-1

I think that at that level you are validating the Json not the parsed object. So you have a string, not a LocalDate.

So basically try changing your code in:

...
.andExpect(jsonPath("$[0].startDate", is("2017-01-01"))));
Into answered 9/10, 2017 at 14:55 Comment(2)
This results into java.lang.AssertionError: JSON path "$[0].startDate" Expected: is "2017-01-01" but: was <[2017,1,1]>Abrasion
better compare with org.springframework.test.web.servlet.result.JsonPathResultMatchers#value, i.e. .andExpect(jsonPath("$[0].startDate").value("2017-01-01"))Troat

© 2022 - 2024 — McMap. All rights reserved.