Is it possible to add an assertion message when using MockMvc?

Viewed 443

Most of the times instead of adding comments in an ordinary JUnit assertion, we add a message to the assertion, to explain why this is assertion is where it is:

Person p1 = new Person("Bob");
Person p2 = new Person("Bob");
assertEquals(p1, p2, "Persons with the same name should be equal.");

Now, when it comes to end point testing in a Spring Boot web environment I end up with this:

// Bad request because body not posted
mockMvc.perform(post("/postregistration")).andExpect(status().isBadRequest());

// Body posted, it should return OK
mockMvc.perform(post("/postregistration").content(toJson(registrationDto))
        .andExpect(status().isOk()));

Is there a way to get rid of the comments and add a message to this kind of assertion? So, when the test fails I will see the message.

2 Answers

I figured out that assertDoesNotThrow responds hence improves the situation (according to what I ask):

assertDoesNotThrow(() -> {
    mockMvc.perform(post("/postregistration")).andExpect(status().isBadRequest());
}, "Bad Request expected since body not posted.");

You can provide a custom ResultMatcher:

mockMvc.perform(post("/postregistration")
        .content(toJson(registrationDto))
        .andExpect(result -> assertEquals("Body posted, it should return OK", HttpStatus.OK.value() , result.getResponse().getStatus())))

mockMvc.perform(post("/postregistration"))
       .andExpect(result -> assertEquals("Bad request because body not posted", HttpStatus.BAD_REQUEST.value(), result.getResponse().getStatus()));

Explaination:

As of today the method .andExpect() accepts only one ResultMatcher. When you use .andExpect(status().isOk()) the class StatusResultMatchers will create a ResultMatcher in this way:

public class StatusResultMatchers {
    //...
    public ResultMatcher isOk() {
        return matcher(HttpStatus.OK);
    }
    //...
    private ResultMatcher matcher(HttpStatus status) {
        return result -> assertEquals("Status", status.value(), result.getResponse().getStatus());
    }
}

As you can see the message is hard-coded to "Status" and there is no other built in method to configure it. So even though providing a custom ResultMatcher is a bit verbose, at the moment might be the only feasible way using mockMvc.

Related