https://meilishiyan-song.taobao.com/

如何在springMVC 中对REST服务使用mockmvc 做测试

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
    错误不好跟踪,必须开着服务器
 
3 使用mockMVC都不是问题了看使用实例:
 
使用事例如下:父类
 
Java代码  收藏代码
  1. import  org.junit.runner.RunWith;  
  2. import  org.springframework.beans.factory.annotation.Autowired;  
  3. import  org.springframework.test.context.ContextConfiguration;  
  4. import  org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  5. import  org.springframework.test.context.web.WebAppConfiguration;  
  6. import  org.springframework.web.context.WebApplicationContext;  
  7.   
  8. @WebAppConfiguration  
  9. @ContextConfiguration (locations = {  "classpath:applicationContext.xml" ,    
  10. "classpath:xxxx-servlet.xml"  })  
  11. public class  AbstractContextControllerTests {   
  12.   
  13.     @Autowired  
  14.     protected  WebApplicationContext wac;  
  15.   
  16. }  
  17.   
  18. 子类:  
  19.   
  20. import  org.junit.Before;  
  21. import  org.junit.Test;  
  22. import  org.junit.runner.RunWith;  
  23. import  org.springframework.beans.factory.annotation.Autowired;  
  24. import  org.springframework.http.MediaType;  
  25. import  org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  26. import  org.springframework.test.web.servlet.MockMvc;  
  27. import  org.springframework.test.web.servlet.setup.MockMvcBuilders;  
  28.   
  29. import  com.conlect.oatos.dto.status.RESTurl;  
  30. import  com.qycloud.oatos.server.service.PersonalDiskService;  
  31.   
  32. //这个必须使用junit4.9以上才有。  
  33. @RunWith (SpringJUnit4ClassRunner. class )  
  34. public class  PersonalDiskMockTests  extends  AbstractContextControllerTests {   
  35.       
  36.       
  37.     private static  String URI = RESTurl.searchPersonalFile;   
  38.   
  39.     private  MockMvc mockMvc;  
  40.       
  41.     private  String json = "{\"entId\":1234,\"userId\":1235,\"key\":\"new\"}" ;  
  42.       
  43.     @Autowired  
  44.     private  PersonalDiskService personalDiskService;  
  45.   
  46.     @Before  
  47.     public void  setup() {   
  48.         //this.mockMvc = webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build();  
  49.         this .mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService).build();  
  50.     }  
  51.   
  52. @Test  
  53.     public void  readJson()  throws  Exception {   
  54.         this .mockMvc.perform(  
  55.                 post(URI,  "json" ).characterEncoding( "UTF-8" )  
  56.                     .contentType(MediaType.APPLICATION_JSON)  
  57.                     .content(json.getBytes()))  
  58.                 .andExpect(content().string( "Read from JSON: JavaBean {foo=[bar], fruit=[apple]}" )  
  59.                     );  
  60.     }  
 
上面是简单的例子,实际使用起来可以稍做修改。记得导入spring -test jar 包。无需额外配置(是不是很方便!)
当然和junit 的assert 一起用的话效果更好。下面贴点例子。copy就能跑。
Java代码  收藏代码
  1. package  com.qycloud.oatos.server.test.mockmvcTest;  
  2.   
  3. import static  org.junit.Assert.fail;   
  4. import static  org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;   
  5.   
  6. import  java.io.UnsupportedEncodingException;  
  7. import  java.lang.reflect.Field;  
  8.   
  9. import  org.springframework.http.MediaType;  
  10. import  org.springframework.test.web.servlet.MockMvc;  
  11.   
  12. import  com.conlect.oatos.dto.status.CommConstants;  
  13. import  com.conlect.oatos.dto.status.ErrorType;  
  14. import  com.conlect.oatos.http.PojoMapper;  
  15.   
  16. public class  MockUtil {   
  17.   
  18.     /** 
  19.      * mock 
  20.      *  
  21.      * @param uri 
  22.      * @param json 
  23.      * @return 
  24.      * @throws UnsupportedEncodingException 
  25.      * @throws Exception 
  26.      */  
  27.     public static  String mock(MockMvc mvc, String uri, String json)   
  28.             throws  UnsupportedEncodingException, Exception {  
  29.         return  mvc  
  30.                 .perform(  
  31.                         post(uri,  "json" ).characterEncoding( "UTF-8" )  
  32.                                 .contentType(MediaType.APPLICATION_JSON)  
  33.                                 .content(json.getBytes())).andReturn()  
  34.                 .getResponse().getContentAsString();  
  35.     }  
  36.   
  37.       
  38.     /** 
  39.      *  
  40.      * @param re 返回值 
  41.      * @param object 要转换的对象 
  42.      * @param testName 当前测试的对象 
  43.      */  
  44.     public static  <T>  void  check(String re, Class<T> object,String testName) {   
  45.         System.out.println(re);  
  46.         if  (ErrorType.error500.toString().equals(re)) {  
  47.             System.out.println( "-----该接口测试失败:-----"  
  48.                     + testName);  
  49.             fail(re);  
  50.         }  else if  (CommConstants.OK_MARK.toString().equals(re)) {   
  51.             System.out.println( "-----该接口测试成功:-----"  
  52.                     + testName);  
  53.         } else {  
  54.             System.out.println( "-----re----- :" +re);  
  55.         }  
  56.         if  (object !=  null ) {  
  57.             if  (re.contains( ":" )) {  
  58.                 try  {  
  59.                     T t = PojoMapper.fromJsonAsObject(re, object);  
  60.                     System.out.println( "-----该接口测试成功:-----"  
  61.                             + testName);  
  62.                 }  catch  (Exception e) {  
  63.                     System.out.println( "-----该接口测试失败:-----"  
  64.                             + testName);  
  65.                     fail(e.getMessage());  
  66.                 }  
  67.             }  
  68.         }  
  69.   
  70.     }  
  71.   
  72.   
  73.     /** 
  74.      * 初始化版本信息。每次调用测试用力之前首先更新版本信息 
  75.      * @param mockMvc 
  76.      * @param url 
  77.      * @param fileId 
  78.      * @param class1 
  79.      * @return 
  80.      * @throws UnsupportedEncodingException 
  81.      * @throws Exception 
  82.      */  
  83.     public static  <T> Long updateVersion(MockMvc mockMvc, String url,   
  84.             Long fileId, Class<T> class1)  throws  UnsupportedEncodingException, Exception {  
  85.           
  86.         String re = mock(mockMvc, url, fileId+ "" );  
  87.           
  88.         T dto = PojoMapper.fromJsonAsObject(re, class1);  
  89.           
  90. Long version = Long.parseLong(dto.getClass().getMethod( "getVersion" ).invoke(dto).toString());     
  91.         System.out.println( "version = " +version);  
  92.           
  93.         return  version;  
  94.           
  95.     }  
  96.       
  97. }  
 使用如下:
Java代码  收藏代码
  1. @RunWith (SpringJUnit4ClassRunner. class )  
  2. public class  PersonalDiskMockTests  extends  AbstractContextControllerTests {   
  3.   
  4.     private  MockMvc mockMvc;  
  5.   
  6.     private static  Long entId = 1234L;   
  7.     private static  Long adminId = 1235L;   
  8.   
  9.   
  10.   
  11.   
  12.     @Autowired  
  13.     private  PersonalDiskService personalDiskService;  
  14.   
  15.     @Before  
  16.     public void  setup() {   
  17.         this .mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService)  
  18.                 .build();  
  19.     }  
  20.   
  21.     /*** 
  22.      * pass 
  23.      * 全局搜索企业文件 
  24.      *  
  25.      * @throws Exception 
  26.      */  
  27.     @Test  
  28.     public void  searchPersonalFile()  throws  Exception {   
  29.   
  30.         SearchFileParamDTO sf =  new  SearchFileParamDTO();  
  31.         sf.setEntId(entId);  
  32.         sf.setKey( "li" );  
  33.         sf.setUserId(adminId);  
  34.   
  35.         String json = PojoMapper.toJson(sf);  
  36.   
  37.         String re = MockUtil.mock( this .mockMvc, RESTurl.searchPersonalFile,  
  38.                 json);  
  39.         MockUtil.check(re, SearchPersonalFilesDTO. class ,  "searchPersonalFile" );  
  40.   
  41.     }  
  42. }  
 当然@setup里面是每个@test执行时都会执行一次的,所以有些需要每次都实例化的参数可以放进来
如下:
Java代码  收藏代码
  1. @Autowired  
  2.     private  ShareDiskService shareDiskService;  
  3.   
  4.     @Before  
  5.     public void  setup() {   
  6.         this .mockMvc = MockMvcBuilders.standaloneSetup(shareDiskService)  
  7.                 .build();  
  8.         try  {  
  9.             initDatas();  
  10.         }  catch  (Exception e) {  
  11.             e.printStackTrace();  
  12.         }  
  13.     }  
  14.   
  15.       
  16.   
  17.     private void  initDatas()  throws  UnsupportedEncodingException, Exception {   
  18.         FileIdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,FileId,ShareFileDTO. class );  
  19.         File2IdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,File2Id,ShareFileDTO. class );  
  20.         oldPicFolderVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFolderById,oldPicFolderId,ShareFolderDTO. class );  
  21.     }  
  22. 以上是我摘抄别人的,以下是我在公司用的写法
  23. 测试类:

  24. package cn.com.mcd;

    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

    import org.codehaus.jackson.map.ObjectMapper;
    import org.junit.Assert;
    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.MvcResult;
    import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;

    import cn.com.mcd.common.ResultModel;
    import cn.com.mcd.controller.StoreLocalPmController;
    import cn.com.mcd.model.StoreLocalPm;

    @RunWith(SpringJUnit4ClassRunner.class)
    public class TestStoreLocalPm extends BaseControllerTest{
    //@Resource
    //private StoreLocalPmService storeLocalPmService;
    @Autowired
    private StoreLocalPmController storeLocalPmController;
    private MockMvc mockMvc;
    @Before
    public void setup() {
    //this.mockMvc = webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build();
    this.mockMvc = MockMvcBuilders.standaloneSetup(storeLocalPmController).build();
    }
    /**
    * 根据条件查询列表
    */
    //@Test
    public void selectStoreLocalPmList() {
    StoreLocalPm storeLocalPm=new StoreLocalPm();
    Long id=1L;
    storeLocalPm.setId(id);//餐厅编号
    storeLocalPm.setStoreName("");//餐厅名称
    storeLocalPm.setAuditStatus("");//审核状态
    ResultModel resultModel=storeLocalPmController.selectStoreLocalPmList(null,storeLocalPm);
    System.out.print("test.resultModel="+resultModel.getResultCode()+"\n"+resultModel.getResultMsg()+"\n"+resultModel.getResultData());
    }
    /**
    * 根据id查询详情
    * @throws Exception
    */
    @Test
    public void selectByPrimaryKey() throws Exception {
    String url = "/storeLocalPm/selectByPrimaryKey";
    StoreLocalPm storeLocalPm =new StoreLocalPm();
    storeLocalPm.setId(1L);

    ObjectMapper mapper = new ObjectMapper();

    String json = mapper.writeValueAsString(storeLocalPm);


    MvcResult result = (MvcResult) mockMvc.perform(post(url)
    .contentType(MediaType.APPLICATION_JSON)
    .content(json)
    .param("epsToken", "token")
    .accept(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk())
    .andDo(MockMvcResultHandlers.print())
    .andReturn();
    System.out.println("----------"+result.getResponse().getStatus());
    System.out.println("----------"+result.getResponse().getContentAsString());
    //Assert.assertEquals(200, result.getResponse().getStatus());
    //Assert.assertNotNull(result.getResponse().getContentAsString());

    //Long id=1L;
    //ResultModel resultModel=storeLocalPmController.selectByPrimaryKey(id);
    //System.out.print("test.resultModel="+resultModel.getResultCode()+"\n"+
    //resultModel.getResultMsg()+"\n"+resultModel.getResultData());

    }
    }

    1. cotroller
    2. package cn.com.mcd.controller;

      import java.util.List;

      import javax.annotation.Resource;

      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.ModelAttribute;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      import org.springframework.web.bind.annotation.ResponseBody;

      import cn.com.mcd.common.ResultModel;
      import cn.com.mcd.model.KitchenEquipmentPrice;
      import cn.com.mcd.model.StoreLocalPm;
      import cn.com.mcd.service.StoreLocalPmService;
      import cn.com.mcd.util.Constants;
      import cn.com.mcd.util.PagesPojo;

      @Controller
      @RequestMapping("/storeLocalPm")
      public class StoreLocalPmController {
      private static final long serialVersionUID = 4515788554984036250L;
      private static final Logger log = LoggerFactory.getLogger(StoreLocalPmController.class);
      @Resource
      private StoreLocalPmService storeLocalPmService;
      /**
      * query detail by id
      * @param id
      * @return
      */
      @RequestMapping(value = "/selectByPrimaryKey", method = RequestMethod.POST)
      @ResponseBody
      public ResultModel selectByPrimaryKey(@RequestBody StoreLocalPm storeLocalPm) {
      log.info(this.getClass().getName()+".selectByPrimaryKey.start.storeLocalPm="+storeLocalPm);
      ResultModel resultModel = new ResultModel();
      try{
      storeLocalPm=storeLocalPmService.selectByPrimaryKey(storeLocalPm.getId());
      log.info(this.getClass().getName()+".selectByPrimaryKey.success.storeLocalPm="+storeLocalPm);
      resultModel.setResultCode(Constants.SERVICE_SUCCESS_CODE);
      resultModel.setResultMsg(Constants.DATA_BASE_SEARCH_SUCCESS_MSG);
      resultModel.setResultData(storeLocalPm);
      }catch(Exception e){
      resultModel.setResultCode(Constants.SERVICE_ERROR_CODE);
      resultModel.setResultMsg(Constants.DATA_BASE_SEARCH_ERROR_MSG);
      }
      log.info(this.getClass().getName()+".selectByPrimaryKey.end.resultModel="+resultModel);
      return resultModel;
      }

      /**
      * query list by param
      * @param id
      * @return
      */
      @RequestMapping(value = "/selectStoreLocalPmList", method = RequestMethod.GET)
      @ResponseBody
      public ResultModel selectStoreLocalPmList(@ModelAttribute PagesPojo<StoreLocalPm> page,StoreLocalPm storeLocalPm) {
      log.info(this.getClass().getName()+".selectStoreLocalPmList.start.page="+page);
      ResultModel result = new ResultModel();
      try{
      int count = storeLocalPmService.countAll(storeLocalPm);
      page.setTotalRow(count);
      List<StoreLocalPm> list = storeLocalPmService.selectStoreLocalPmList(page);
      page.setPages(list);
      result.setResultCode(Constants.SERVICE_SUCCESS_CODE);
      result.setResultMsg(Constants.DATA_BASE_SEARCH_SUCCESS_MSG);
      result.setResultData(page);
      }catch(Exception e){
      result.setResultCode(Constants.SERVICE_ERROR_CODE);
      result.setResultMsg(Constants.DATA_BASE_SEARCH_ERROR_MSG);
      }
      log.info(this.getClass().getName()+".selectStoreLocalPmList.end.result="+result);
      return result;
      }
      int deleteByPrimaryKey(Long id){
      return 0;

      }


      int insert(StoreLocalPm record) {
      return 0;
      }

      int insertSelective(StoreLocalPm record){
      return 0;

      }


      int updateByPrimaryKeySelective(StoreLocalPm record) {
      return 0;
      }

      int updateByPrimaryKey(StoreLocalPm record) {
      return 0;
      }
      }

posted @ 2017-01-07 13:32  望梦圆  阅读(2044)  评论(1编辑  收藏  举报
https://meilishiyan-song.taobao.com/