43

I have a simple Spring test

@Test
public void getAllUsers_AsPublic() throws Exception {
    doGet("/api/users").andExpect(status().isForbidden());
}

public ResultActions doGet(String url) throws Exception {
    return mockMvc.perform(get(url).header(header[0],header[1])).andDo(print());
}

I would like to verify that the response body is empty. E.g. Do something like .andExpect(content().isEmpty())

DaveyDaveDave
  • 9,821
  • 11
  • 64
  • 77
isADon
  • 3,433
  • 11
  • 35
  • 49

3 Answers3

68

There's a cleaner way:

andExpect(jsonPath("$").doesNotExist())

Note that you can't use isEmpty because it checks for an empty value, and assumes the existence of the attribute. When the attribute doesn't exist, isEmpty throws an exception. Whereas, doesNotExist verifies that the attribute doesn't exist, and when used with $, it checks for an empty JSON document.

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
  • 2
    One caveat is that `andExpect(jsonPath("$").doesNotExist())` will silently succeed when the content body exists and contains the string `null` (without quotes), which may or may not be what you want. I tested this on version 2.4.0. – Chris H. Feb 11 '20 at 20:44
  • @ChrisH. Interesting, but an edge case. `null` gets special treatment in JSON, so if all the attributes have the value `null`, an argument can be made that it’s as good as empty. As a developer, I’d question the design rather than the behavior; why’d anyone include `null` attributes, other than to confuse clients. Most JSON libraries, like Jackson, have the option to omit writing out `null` attributes. – Abhijit Sarkar Feb 12 '20 at 00:52
  • @AbhijitSarkar - I'm getting "java.lang.AssertionError: No value at JSON path $" when applied to a non-JSON response. – wh81752 Dec 30 '22 at 18:03
  • @wh81752 that’s like saying there’s something wrong with the hammer because you can’t tighten a screw with it. Instead of hijacking this thread, I recommend opening a new question. – Abhijit Sarkar Dec 31 '22 at 01:53
  • 1
    @AbhijitSarkar - you are on the right track with hammer and screw. Because your "JSON" hammer does not fit the *any* content screw. Your answer assumes JSON as content-type which is not justified given the original question. Btw, see my answer below for a more generic solution. – wh81752 Dec 31 '22 at 14:47
  • .andExpect(status().isNoContent()) should be good enough. – SUMIT Jul 11 '23 at 05:01
16

I think one of these options should achieve what you're looking for, although not quite as nice as an isEmpty() (from the ContentResultMatchers documentation):

.andExpect(content().bytes(new Byte[0])

or

.andExpect(content().string(""))
Michael Lihs
  • 7,460
  • 17
  • 52
  • 85
DaveyDaveDave
  • 9,821
  • 11
  • 64
  • 77
  • I'm surprised this ever worked @DaveyDaveDave. I tried this with version 2.2.4.RELEASE of Spring Boot (with managed dependencies from `spring-boot-starter-parent`) with a response with no body. Abhijit's answer works. The string approach from your answer yields `Response content expected:<> but was:`. Then if you use `.string( (String) null)` you get `Response content expected: but was:`. Huh??? The bytes approach from your answer yields `Response content expected:<{}> but was:<{110, 117, 108, 108}>` (which is puzzling because MockHttpServletResponse logs Body = `null`). – Chris H. Feb 06 '20 at 16:41
  • 1
    I see. The [ASCII values](http://www.asciitable.com/) 110, 117 and 108 are "n", "u" and "l" respectively. What you have is a response containing the literal word "null", not an empty response. I suspect `.andExpect(content().string("null"))` will pass. – DaveyDaveDave Feb 07 '20 at 07:47
  • 2
    You are correct @DaveyDaveDave, and thank you. Funny I missed that. In this case, the fact that the expectation for `jsonPath("$").doesNotExist()` does not fail is an issue. – Chris H. Feb 11 '20 at 20:04
1

May I suggest to use either (A) or (B)

import org.hamcrest.Matchers;
...
mockMvc.perform(..)
  .andExpect(content().string(Matchers.blankOrNullString())) // (A)
  .andExpect(content().string(Matchers.blankString()))       // (B)

Tested with hamcrest:2.2

wh81752
  • 869
  • 9
  • 16