42

I am currently writing some unit tests for a Spring MVC project. As the returned media type is JSON, I try to use jsonPath to check if the correct values are returned.

The trouble I have is to verify if a list of strings contains the correct (and only the correct) values.

My Plan was:

  1. Check that the list has the correct length
  2. For each element that's supposed to be returned, check whether it's in the list

sadly, none of these things seem to work.

Here's the relevant part of my code:

Collection<AuthorityRole> correctRoles = magicDataSource.getRoles();

ResultActions actions = this.mockMvc.perform(get("/accounts/current/roles").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()) // works
.andExpect(jsonPath("$.data.roles").isArray()) // works
.andExpect(jsonPath("$.data.roles.length").value(correctRoles.size())); // doesn't work

for (AuthorityRole role : correctRoles) // doesn't work
  actions.andExpect(jsonPath("$.data.roles[?(@=='%s')]", role.toString()).exists());

Only the first two "expectations" (isOk & isArray) are working. The other ones (for length and content) I can twist and turn however I want, they're not giving me any useful result.

Any suggestions?

2 Answers 2

88

1) Instead of

.andExpect(jsonPath("$.data.roles.length").value(correctRoles.size()));

try

.andExpect(jsonPath("$.data.roles.length()").value(correctRoles.size()));

or

.andExpect((jsonPath("$.data.roles", Matchers.hasSize(size))));

2) Instead of

for (AuthorityRole role : correctRoles) // doesn't work
  actions.andExpect(jsonPath("$.data.roles[?(@=='%s')]", role.toString()).exists());

try

actions.andExpect((jsonPath("$.data.roles", Matchers.containsInAnyOrder("role1", "role2", "role3"))));

Keep in mind that you have to add hamcrest-library.

Sign up to request clarification or add additional context in comments.

3 Comments

@chaldaean What hamcrest library are you using? In the one I have, hamcrest-all-1.1, the class org.hamcrest.Matchers does not contain the methods hasSize and containsInAnyOrder.
This one - hamcrest-library 1.2.1
For completeness, Hamcrest Matchers can also be added to the value method so andExpect(jsonPath("$.data.roles").value(Matchers.containsInAnyOrder(items...)) is just as legal.
7

Here is what I ended up using:

.andExpect(jsonPath('$.data.roles').value(Matchers.hasSize(size)))

and

.andExpect(jsonPath('$.data.roles').value(Matchers.containsInAnyOrder("role1", "role2", "role3")))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.