323

簡単な統合テストがあります

@Test
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception {
    mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
        .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
        .andDo(print())
        .andExpect(status().isBadRequest())
        .andExpect(?);
}

最後の行で、応答本文で受信した文字列を予想される文字列と比較したい

そしてそれに応じて私は得る:

MockHttpServletResponse:
          Status = 400
   Error message = null
         Headers = {Content-Type=[application/json]}
    Content type = application/json
            Body = "Username already taken"
   Forwarded URL = null
  Redirected URL = null

content()、body() でいくつかのトリックを試しましたが、何も機能しませんでした。

4

12 に答える 12

138

@Sotirios Delimanolisの回答は仕事をしますが、このmockMvcアサーション内で文字列を比較することを探していました

だからここにあります

.andExpect(content().string("\"Username already taken - please try with different username\""));

もちろん、私の主張は失敗します:

java.lang.AssertionError: Response content expected:
<"Username already taken - please try with different username"> but was:<"Something gone wrong">

なぜなら:

  MockHttpServletResponse:
            Body = "Something gone wrong"

これは効果がある証拠です!

于 2013-08-20T17:13:43.200 に答える
67

これらの回答を読むと、Spring バージョン 4.x に関連する多くのことがわかります。さまざまな理由でバージョン 3.2.0 を使用しています。そのため、json から直接サポートすることcontent()はできません。

使い方MockMvcResultMatchers.jsonPathは本当に簡単で、おやつに効果があることがわかりました。post メソッドをテストする例を次に示します。

このソリューションのボーナスは、完全な json 文字列の比較に依存するのではなく、引き続き属性を照合していることです。

(使用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));

リクエストの本文は単なる json 文字列であり、必要に応じて実際の json モック データ ファイルから簡単にロードできますが、質問から逸脱する可能性があるため、ここには含めませんでした。

返される実際の json は次のようになります。

{
    "data":"some value"
}
于 2016-02-05T14:24:53.323 に答える
9

JSON 応答を解析する方法と、JSON 形式の Bean を使用してリクエストを送信する方法の例を次に示します。

  @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());
  }

ここでわかるように、Bookはリクエスト DTO で、UpdateBookResponseは JSON から解析されたレスポンス オブジェクトです。Jackson の構成を変更したい場合がありObjectMapperます。

于 2019-08-09T08:32:40.343 に答える
9

ここでよりエレガントな方法

mockMvc.perform(post("/retrieve?page=1&countReg=999999")
            .header("Authorization", "Bearer " + validToken))
            .andExpect(status().isOk())
            .andExpect(content().string(containsString("regCount")));
于 2019-08-06T18:44:34.000 に答える