How to check String in response body with mockMvc

后端 未结 12 1851
遇见更好的自我
遇见更好的自我 2020-12-02 04:02

I have simple integration test

@Test
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName()          


        
相关标签:
12条回答
  • 2020-12-02 04:45

    Another option is:

    when:
    
    def response = mockMvc.perform(
                get('/path/to/api')
                .header("Content-Type", "application/json"))
    
    then:
    
    response.andExpect(status().isOk())
    response.andReturn().getResponse().getContentAsString() == "what you expect"
    
    0 讨论(0)
  • 2020-12-02 04:47
    String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage()
    

    This should give you the body of the response. "Username already taken" in your case.

    0 讨论(0)
  • 2020-12-02 04:48

    You can use getContentAsString method to get the response data as string.

        String payload = "....";
        String apiToTest = "....";
        
        MvcResult mvcResult = mockMvc.
                    perform(post(apiToTest).
                    content(payload).
                    contentType(MediaType.APPLICATION_JSON)).
                    andReturn();
        
        String responseData = mvcResult.getResponse().getContentAsString();
    

    You can refer this link for test application.

    0 讨论(0)
  • 2020-12-02 04:53

    here a more elegant way

    mockMvc.perform(post("/retrieve?page=1&countReg=999999")
                .header("Authorization", "Bearer " + validToken))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("regCount")));
    
    0 讨论(0)
  • 2020-12-02 04:53

    Here is an example how to parse JSON response and even how to send a request with a bean in JSON form:

      @Autowired
      protected MockMvc mvc;
    
      private static final ObjectMapper MAPPER = new ObjectMapper()
        .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .registerModule(new JavaTimeModule());
    
      public static String requestBody(Object request) {
        try {
          return MAPPER.writeValueAsString(request);
        } catch (JsonProcessingException e) {
          throw new RuntimeException(e);
        }
      }
    
      public static <T> T parseResponse(MvcResult result, Class<T> responseClass) {
        try {
          String contentAsString = result.getResponse().getContentAsString();
          return MAPPER.readValue(contentAsString, responseClass);
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    
      @Test
      public void testUpdate() {
        Book book = new Book();
        book.setTitle("1984");
        book.setAuthor("Orwell");
        MvcResult requestResult = mvc.perform(post("http://example.com/book/")
          .contentType(MediaType.APPLICATION_JSON)
          .content(requestBody(book)))
          .andExpect(status().isOk())
          .andReturn();
        UpdateBookResponse updateBookResponse = parseResponse(requestResult, UpdateBookResponse.class);
        assertEquals("1984", updateBookResponse.getTitle());
        assertEquals("Orwell", updateBookResponse.getAuthor());
      }
    

    As you can see here the Book is a request DTO and the UpdateBookResponse is a response object parsed from JSON. You may want to change the Jackson's ObjectMapper configuration.

    0 讨论(0)
  • 2020-12-02 04:54

    Reading these answers, I can see a lot relating to Spring version 4.x, I am using version 3.2.0 for various reasons. So things like json support straight from the content() is not possible.

    I found that using MockMvcResultMatchers.jsonPath is really easy and works a treat. Here is an example testing a post method.

    The bonus with this solution is that you're still matching on attributes, not relying on full json string comparisons.

    (Using org.springframework.test.web.servlet.result.MockMvcResultMatchers)

    String expectedData = "some value";
    mockMvc.perform(post("/endPoint")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(mockRequestBodyAsString.getBytes()))
                    .andExpect(status().isOk())
                    .andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData));
    

    The request body was just a json string, which you can easily load from a real json mock data file if you wanted, but I didnt include that here as it would have deviated from the question.

    The actual json returned would have looked like this:

    {
        "data":"some value"
    }
    
    0 讨论(0)
提交回复
热议问题