I'm writing unit tests for Spring HATEOAS backend using MockMvc and JsonPath. To test the links contained in a response I'm doing something like:
@Test
public void testListEmpty() throws Exception {
mockMvc.perform(get("/rest/customers"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.links", hasSize(1))) // make sure links only contains self link
.andExpect(jsonPath("$.links[?(@.rel=='self')]", hasSize(1))) // make sure the self link exists 1 time
.andExpect(jsonPath("$.links[?(@.rel=='self')].href", contains("http://localhost/rest/customers{?page,size,sort}"))) // test self link is correct
.andExpect(jsonPath("$.links[?(@.rel=='self')][0].href", is("http://localhost/rest/customers{?page,size,sort}"))) // alternative to test self link is correct
.andExpect(jsonPath("$.content", hasSize(0))); // make sure no content elements exists
}
However I wonder if there are some best practices I should use to make it easier for myself like:
- Testing link contains
http://localhost
does not feel right. Can I use some Spring MovkMvc helper to determine the host? - With JsonPath it's difficult to test if an array contains an element where 2 attributes have certain value. Like that the array should contain a self link with a certain value. Is there a better way to test that then above This will also come into play when testing validation errors for fields with error messages.
I've see technique like below in some blog posts:
.andExpect(jsonPath("$.fieldErrors[*].path", containsInAnyOrder("title", "description")))
.andExpect(jsonPath("$.fieldErrors[*].message", containsInAnyOrder(
"The maximum length of the description is 500 characters.",
"The maximum length of the title is 100 characters.")));
But this does not guarantee at all that title has the specific error message. It could also be that the title has incorrectly the "The maximum length of the description is 500 characters." but the test will succeed.