SpringのMockMVCフレームワークを使用してデータベースにオブジェクトをポストするメソッドをテストしようとしています。次のようにテストを作成しました。
@Test
public void testInsertObject() throws Exception {
String url = BASE_URL + "/object";
ObjectBean anObject = new ObjectBean();
anObject.setObjectId("33");
anObject.setUserId("4268321");
//... more
Gson gson = new Gson();
String json = gson.toJson(anObject);
MvcResult result = this.mockMvc.perform(
post(url)
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andReturn();
}
私がテストしているメソッドは、Springの@RequestBodyを使用してObjectBeanを受け取りますが、テストは常に400エラーを返します。
@ResponseBody
@RequestMapping( consumes="application/json",
produces="application/json",
method=RequestMethod.POST,
value="/object")
public ObjectResponse insertObject(@RequestBody ObjectBean bean){
this.photonetService.insertObject(bean);
ObjectResponse response = new ObjectResponse();
response.setObject(bean);
return response;
}
テストでgsonによって作成されたjson:
{
"objectId":"33",
"userId":"4268321",
//... many more
}
ObjectBeanクラス
public class ObjectBean {
private String objectId;
private String userId;
//... many more
public String getObjectId() {
return objectId;
}
public void setObjectId(String objectId) {
this.objectId = objectId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
//... many more
}
だから私の質問は次のとおりです。SpringMockMVCを使用してこの方法をテストする方法は?
これを使用してください
public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
@Test
public void testInsertObject() throws Exception {
String url = BASE_URL + "/object";
ObjectBean anObject = new ObjectBean();
anObject.setObjectId("33");
anObject.setUserId("4268321");
//... more
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
String requestJson=ow.writeValueAsString(anObject );
mockMvc.perform(post(url).contentType(APPLICATION_JSON_UTF8)
.content(requestJson))
.andExpect(status().isOk());
}
コメントで説明されているように、オブジェクトがjsonに変換されてリクエスト本文として渡されるため、これは機能します。さらに、contentTypeはJson(APPLICATION_JSON_UTF8)として定義されています。
私のために次の作品、
mockMvc.perform(
MockMvcRequestBuilders.post("/api/test/url")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(createItemForm)))
.andExpect(status().isCreated());
public static String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
問題は、アプリケーションがJSONをJackson Gson
(MappingJackson2HttpMessageConverter
内)でデシリアライズしようとしている間に、カスタムObjectMapper
オブジェクトでBeanをシリアライズしていることです。
サーバーログを開くと、次のように表示されます。
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of Java.util.Date from String value '2013-34-10-10:34:31': not a valid representation (error: Failed to parse Date value '2013-34-10-10:34:31': Can not parse date "2013-34-10-10:34:31": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
at [Source: Java.io.StringReader@baea1ed; line: 1, column: 20] (through reference chain: com.spring.Bean["publicationDate"])
とりわけスタックトレース。
1つの解決策は、Gson
日付形式を上記のいずれかに設定することです(スタックトレースで)。
別の方法は、ObjectMapper
と同じ日付形式を持つように独自のGson
を構成することにより、独自のMappingJackson2HttpMessageConverter
を登録することです。