如何在springMVC 中对REST服务使用mockmvc 做测试
2015-07-10 · 知道合伙人数码行家
知道合伙人数码行家
向TA提问 私信TA
spring 集成测试中 对mock 的集成实在是太棒了!但是使用请注意一下3个条件。
junit 必须使用4.9以上
同时您的框架必须是用spring mvc
spring 3.2以上才完美支持
目前使用spring MVC 取代struts2 的很多,spring MVC 的各种灵活让人无比销魂!所以使用spring MVC吧!
以前在对接口(主要是java服务端提供的接口(一般是:webService,restful))进行测试的中 一般用以下俩种方法。测试流程如图:
1 直接使用httpClient
这方法各种麻烦
2 使用Spring 提供的RestTemplate
错误不好跟踪,必须开着服务器
使用mockMVC都不是问题了看使用实例:
使用事例如下:父类
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;
@WebAppConfiguration
@ContextConfiguration(locations = { "classpath:applicationContext.xml",
"classpath:xxxx-servlet.xml" })
public class AbstractContextControllerTests {
@Autowired
protected WebApplicationContext wac;
}
子类:
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.conlect.oatos.dto.status.RESTurl;
import com.qycloud.oatos.server.service.PersonalDiskService;
//这个必须使用junit4.9以上才有。
@RunWith(SpringJUnit4ClassRunner.class)
public class PersonalDiskMockTests extends AbstractContextControllerTests {
private static String URI = RESTurl.searchPersonalFile;
private MockMvc mockMvc;
private String json ="{\"entId\":1234,\"userId\":1235,\"key\":\"new\"}";
@Autowired
private PersonalDiskService personalDiskService;
@Before
public void setup() {
//this.mockMvc = webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build();
this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService).build();
}
@Test
public void readJson() throws Exception {
this.mockMvc.perform(
post(URI, "json").characterEncoding("UTF-8")
.contentType(MediaType.APPLICATION_JSON)
.content(json.getBytes()))
.andExpect(content().string("Read from JSON: JavaBean {foo=[bar], fruit=[apple]}")
);
}
上面是简单的例子,实际使用起来可以稍做修改。记得导入spring -test jar 包。无需额外配置(是不是很方便!)
当然和junit 的assert 一起用的话效果更好。下面贴点例子。copy就能跑。
Java代码
package com.qycloud.oatos.server.test.mockmvcTest;
import static org.junit.Assert.fail;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import com.conlect.oatos.dto.status.CommConstants;
import com.conlect.oatos.dto.status.ErrorType;
import com.conlect.oatos.http.PojoMapper;
public class MockUtil {
/**
* mock
*
* @param uri
* @param json
* @return
* @throws UnsupportedEncodingException
* @throws Exception
*/
public static String mock(MockMvc mvc, String uri, String json)
throws UnsupportedEncodingException, Exception {
return mvc
.perform(
post(uri, "json").characterEncoding("UTF-8")
.contentType(MediaType.APPLICATION_JSON)
.content(json.getBytes())).andReturn()
.getResponse().getContentAsString();
}
/**
*
* @param re 返回值
* @param object 要转换的对象
* @param testName 当前测试的对象
*/
public static <T> void check(String re, Class<T> object,String testName) {
System.out.println(re);
if (ErrorType.error500.toString().equals(re)) {
System.out.println("-----该接口测试失败:-----"
+ testName);
fail(re);
} else if (CommConstants.OK_MARK.toString().equals(re)) {
System.out.println("-----该接口测试成功:-----"
+ testName);
}else{
System.out.println("-----re----- :"+re);
}
if (object != null) {
if (re.contains(":")) {
try {
T t = PojoMapper.fromJsonAsObject(re, object);
System.out.println("-----该接口测试成功:-----"
+ testName);
} catch (Exception e) {
System.out.println("-----该接口测试失败:-----"
+ testName);
fail(e.getMessage());
}
}
}
}
/**
* 初始化版本信息。每次调用测试用力之前首先更新版本信息
* @param mockMvc
* @param url
* @param fileId
* @param class1
* @return
* @throws UnsupportedEncodingException
* @throws Exception
*/
public static <T> Long updateVersion(MockMvc mockMvc, String url,
Long fileId, Class<T> class1) throws UnsupportedEncodingException, Exception {
String re = mock(mockMvc, url, fileId+"");
T dto = PojoMapper.fromJsonAsObject(re, class1);
Long version = Long.parseLong(dto.getClass().getMethod("getVersion").invoke(dto).toString());
System.out.println("version = "+version);
return version;
}
}
使用如下:
Java代码
@RunWith(SpringJUnit4ClassRunner.class)
public class PersonalDiskMockTests extends AbstractContextControllerTests {
private MockMvc mockMvc;
private static Long entId = 1234L;
private static Long adminId = 1235L;
@Autowired
private PersonalDiskService personalDiskService;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService)
.build();
}
/***
* pass
* 全局搜索企业文件
*
* @throws Exception
*/
@Test
public void searchPersonalFile() throws Exception {
SearchFileParamDTO sf = new SearchFileParamDTO();
sf.setEntId(entId);
sf.setKey("li");
sf.setUserId(adminId);
String json = PojoMapper.toJson(sf);
String re = MockUtil.mock(this.mockMvc, RESTurl.searchPersonalFile,
json);
MockUtil.check(re, SearchPersonalFilesDTO.class, "searchPersonalFile");
}
}
当然@setup里面是每个@test执行时都会执行一次的,所以有些需要每次都实例化的参数可以放进来
如下:
Java代码
@Autowired
private ShareDiskService shareDiskService;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(shareDiskService)
.build();
try {
initDatas();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initDatas() throws UnsupportedEncodingException, Exception {
FileIdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,FileId,ShareFileDTO.class);
File2IdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,File2Id,ShareFileDTO.class);
oldPicFolderVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFolderById,oldPicFolderId,ShareFolderDTO.class);
}
ok!基本使用大致如此,代码没有些注释,但是很简单,看懂是没问题的。权当抛砖引玉。希望大家加以指正!