Mat*_*att 47 integration-testing spring-mvc
我正在尝试使用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();
}
Run Code Online (Sandbox Code Playgroud)
我正在测试的方法使用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;
}
Run Code Online (Sandbox Code Playgroud)
gson在测试中创建的json:
{
"objectId":"33",
"userId":"4268321",
//... many more
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:如何使用Spring MockMVC测试此方法?
小智 66
使用这个
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());
}
Run Code Online (Sandbox Code Playgroud)
正如评论中所描述的那样,这是有效的,因为对象被转换为json并作为请求体传递.此外,contentType定义为Json(APPLICATION_JSON_UTF8).
Vic*_*cky 11
以下对我有用
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我在最新版本的 Spring 中遇到了类似的问题。我尝试使用 anew ObjectMapper().writeValueAsString(...)但它在我的情况下不起作用。
我实际上有一个StringJSON 格式的,但我觉得它实际上是将toString()每个字段的方法转换为 JSON。就我而言,日期LocalDate字段最终将如下所示:
“日期”:{“年份”:2021,“月份”:“一月”,“月份值”:1,“月份日期”:1,“年表”:{“id”:“ISO”,“日历类型”:“iso8601 "},"dayOfWeek":"星期五","leapYear":false,"dayOfYear":1,"era":"CE"}
这不是在请求中发送的最佳日期格式......
最后,就我而言,最简单的解决方案是使用 Spring ObjectMapper. 它的行为更好,因为它使用 Jackson 来构建具有复杂类型的 JSON。
@Autowired
private ObjectMapper objectMapper;
Run Code Online (Sandbox Code Playgroud)
我只是在测试中使用了它:
mockMvc.perform(post("/api/")
.content(objectMapper.writeValueAsString(...))
.contentType(MediaType.APPLICATION_JSON)
);
Run Code Online (Sandbox Code Playgroud)
问题在于,Gson当应用程序尝试使用Jackson ObjectMapper(在中MappingJackson2HttpMessageConverter)反序列化JSON时,您正在使用自定义对象序列化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"])
Run Code Online (Sandbox Code Playgroud)
在其他堆栈跟踪中。
一种解决方案是将Gson日期格式设置为上述格式之一(在stacktrace中)。
另一种方法是MappingJackson2HttpMessageConverter通过配置自己ObjectMapper的日期格式与自己的日期相同来注册自己的日期Gson。
| 归档时间: |
|
| 查看次数: |
85967 次 |
| 最近记录: |