在我的Spring项目中,我创建了一些检查控制器/ http-api的测试。有没有办法将响应的json内容作为反序列化对象?
在其他项目中,我使用了放心的方法,并且有方法直接将结果作为预期的对象来获取。
这里是一个例子:
MvcResult result = rest.perform( get( "/api/byUser" ).param( "userName","test_user" ) )
.andExpect( status().is( HttpStatus.OK.value() ) ).andReturn();
String string = result.getResponse().getContentAsString();
该方法返回特定类型的json。如何将此json转换回对象以测试其内容? 我知道杰克逊的方法或放心的方法,但是spring / test / mockmvc中是否有方法
像getContentAs(Class)
答案 0 :(得分:4)
据我所知MockHttpServletResponse
(与RestTemplate不同)没有任何方法可以将返回的json转换为特定类型
因此,您可以使用Jakson ObjectMapper
将json字符串转换为特定类型
类似这样
String json = rt.getResponse().getContentAsString();
SomeClass someClass = new ObjectMapper().readValue(json, SomeClass.class);
这将使您拥有更多控制权,可以主张不同的事情。
话虽如此,MockMvc::perform
返回ResultActions
,它具有方法andExpect
,该方法采用ResultMatcher
。这有很多选项可以测试结果json,而无需将其转换为对象。
例如
mvc.perform( .....
......
.andExpect(status().isOk())
.andExpect(jsonPath("$.firstname").value("john"))
.andExpect(jsonPath("$.lastname").value("doe"))
.andReturn();
答案 1 :(得分:0)
这可能有用:
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.togondo.config.database.MappingConfig;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultHandler;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Getter
public class CustomResponseHandler<T> implements ResultHandler {
private final Class<? extends Collection> collectionClass;
private T responseObject;
private String responseData;
private final Class<T> type;
private Map<String, String> headers;
private String contentType;
public CustomResponseHandler() {
this.type = null;
this.collectionClass = null;
}
public CustomResponseHandler(Class type) {
this.type = type;
this.collectionClass = null;
}
public CustomResponseHandler(Class type, Class<? extends Collection> collectionClass) {
this.type = type;
this.collectionClass = collectionClass;
}
protected <T> T responseToObject(MockHttpServletResponse response, Class<T> type) throws IOException {
String json = getResponseAsContentsAsString(response);
if (org.apache.commons.lang3.StringUtils.isEmpty(json)) {
return null;
}
return MappingConfig.getObjectMapper().readValue(json, type);
}
protected <T> T responseToObjectCollection(MockHttpServletResponse response, Class<? extends Collection> collectionType, Class<T> collectionContents) throws IOException {
String json = getResponseAsContentsAsString(response);
if (org.apache.commons.lang3.StringUtils.isEmpty(json)) {
return null;
}
ObjectMapper mapper = MappingConfig.getObjectMapper();
JavaType type = mapper.getTypeFactory().constructCollectionType(collectionType, collectionContents);
return mapper.readValue(json, type);
}
protected String getResponseAsContentsAsString(MockHttpServletResponse response) throws IOException {
String content = "";
BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(response.getContentAsByteArray())));
String line;
while ((line = br.readLine()) != null)
content += line;
br.close();
return content;
}
@Override
public void handle(MvcResult result) throws Exception {
if( type != null ) {
if (collectionClass != null) {
responseObject = responseToObjectCollection(result.getResponse(), collectionClass, type);
} else {
responseObject = responseToObject(result.getResponse(), type);
}
}
else {
responseData = getResponseAsContentsAsString(result.getResponse());
}
headers = getHeaders(result);
contentType = result.getResponse().getContentType();
if (result.getResolvedException() != null) {
log.error("Exception: {}", result.getResponse().getErrorMessage());
log.error("Error: {}", result.getResolvedException());
}
}
private Map<String, String> getHeaders(MvcResult result) {
Map<String, String> headers = new HashMap<>();
result.getResponse().getHeaderNames().forEach(
header -> headers.put(header, result.getResponse().getHeader(header))
);
return headers;
}
public String getHeader(String headerName) {
return headers.get(headerName);
}
public String getContentType() {
return contentType;
}
}
然后像这样在你的测试中使用它:
CustomResponseHandler<MyObject> responseHandler = new CustomResponseHandler(MyObject.class);
mockMvc.perform(MockMvcRequestBuilders.get("/api/yourmom"))
.andDo(responseHandler)
.andExpect(status().isOk());
MyObject myObject = responseHandler.getResponseObject();
或者如果您想获取集合:
CustomResponseHandler<Set<MyObject>> responseHandler = new CustomResponseHandler(MyObject.class, Set.class);
.
.
.
Set<MyObject> myObjectSet = responseHandler.getResponseObject();