spring-mock 进行单元测试

今天花了下午的时间研究了下如何对Controller层的代码进行单元测试.

踩了不少的坑,现在总结一下

 严重注意 :

 spring4开始已经不兼容Servlet2 否则会报错,很多坑都是这个引起的.
 Servlet3指的是 3.0.1以后的  artifactId为    <artifactId>javax.servlet-api</artifactId>
 Servlet2指的是 3.0.1以前的  artifactId为  <artifactId>servlet-api</artifactId>
 
 只是做了一个普通的例子,大家可以根据自己的需求查看api,找到解决办法.

PS:看别人的博客,坑比较多
 

package com.kbs.service;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;

import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;

import java.io.IOException;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;  
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;  
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;  

import org.aspectj.apache.bcel.classfile.Utility.ResultHolder;
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.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.web.context.WebApplicationContext;

import com.kbs.platform.controller.WDController;
/**
 * 
 * @author mifans

 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration  
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class SpringMockTest {

	@Autowired  
	WDController wDController;
	@Autowired  
	ServletContext context; 
	
	 @Autowired
	protected WebApplicationContext wac;

	MockMvc mockMvc;  
    MockHttpSession session;  
    @Before  
    public void setup(){  
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); //这个方法接受 WebApplicationContext参数,可以对任意Controller测试
       // mockMvc =MockMvcBuilders.standaloneSetup(wDController).build(); 可以对单独的Controller测试
        //mockMvc =MockMvcBuilders.standaloneSetup(context).build();      测试未成功,应该是和spring的配置有关系
        session= new MockHttpSession(); //可以使用session 对于包含登录的,需要验证session中的数据 
    } 
    //saas/qa?k=糖尿病怎么办
    String param="糖尿病怎么办";
    @Test
    public void test() throws Exception{
    	ResultActions resultActions = this.mockMvc.perform(MockMvcRequestBuilders.get("/qa")
    			.param("k",param).session(session)).andExpect(status().isOk())  
                //.andExpect(content().contentType("application/json;charset=UTF-8"))  
                .andDo(print()); //这里需要需要一定要引入spring测试框架的几个静态方法类,否则找不到print(),content()方法.
    	        //对于返回json格式的可以用.accept(MediaType.APPLICATION_JSON)处理,不了解的多研究api
       
    	
    	MvcResult mvcResult = resultActions.andReturn();  
        String result = mvcResult.getResponse().getContentLength()+""; 
        Cookie[] cookies=mvcResult.getResponse().getCookies();
        
        
//        for (int i = 0; i < cookies.length; i++) {
//        	System.err.println(cookies[i].getName()+"--------"+cookies[i].getValue());
//		}
        System.out.println("=====客户端获得反馈数据:" + result);  
    }
    @Test  
    public void testLogin() throws IOException {  
        
      //  MockHttpServletRequest request = new MockHttpServletRequest();  
        //MockHttpServletResponse response = new MockHttpServletResponse();  
        
        //request.setMethod("POST");  
        //request.addParameter("k",param);  
    	//对于确定参数的,并且参数可以构造出来的可以这么测试.以下测试成功
        wDController.wdResult(param, null, null, new ExtendedModelMap());  
    }  
	
    
	  
}

WDCController.java

package com.kbs.platform.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.kbs.platform.service.WDService;
import com.kbs.platform.vo.WDMsgBody;

@Controller("wDController")
@RequestMapping("/")
public class WDController {
	@Autowired
	public WDService wDService;
	
	/**
	 * 首页
	 * @return
	 */
	@RequestMapping(value="qasearch",method=RequestMethod.GET)
	public String wd(){
		return "wd/index";
	}
	
	@RequestMapping(value="qa",method=RequestMethod.GET)
	public String wdResult(@RequestParam("k")String key,@RequestParam(value="p",required=false)Integer startNum,@RequestParam(value="s",required=false)Integer pageSize,Model model){
		startNum=startNum==null?1:startNum;
		pageSize=pageSize==null?WDService.PAGESIZE:pageSize;
		
		/**
		 * 此处为赶时间,先做成jsp渲染的,后期如果使用anglarjs的话,直接修改该方法的返回值为json格式即可
		 */
		WDMsgBody wdMsgBody=wDService.accessNLP(key, startNum, pageSize);
		
		//拆分封装数据格式
		model.addAttribute("data", wdMsgBody.getData());//数据
		model.addAttribute("key",wdMsgBody.getKey()); //问题
		model.addAttribute("curPage",wdMsgBody.getCurPage());//当前页
		model.addAttribute("pageSize",wdMsgBody.getPageSize());//页面数据条数
		model.addAttribute("total",wdMsgBody.getTotal()); //数据总条数
		model.addAttribute("totalPage",wdMsgBody.getTotalPage()); //总页数
		return "wd/qa";
	}
	

}

 

贴一个静态方法 print()的打印结果  Controller返回的是视图

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /qa
       Parameters = {k=[糖尿病怎么办]}
          Headers = {}

Handler:
             Type = com.kbs.platform.controller.WDController

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = wd/qa
             View = null
        Attribute = data
            value = [数据结果-略去]
        Attribute = key
            value = 糖尿病怎么办
        Attribute = curPage
            value = 1
        Attribute = pageSize
            value = 10
        Attribute = total
            value = 546
        Attribute = totalPage
            value = 55

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = wd/qa
   Redirected URL = null

也可以自己实现 ResultHandler 接口,下面是我的一个例子,当时没找到print()方法怎么来的,就自己实现了一个,现在看来,并没有什么卵用 (╥╯^╰╥)

package com.kbs.service;

import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultHandler;

class myHandler implements ResultHandler {

	public myHandler() {
		// TODO Auto-generated constructor stub
	}
	@Override
	public void handle(MvcResult result) throws Exception {
		System.err.println(result.getRequest().getRequestURI());
		System.err.println(result.getResponse().getContentAsString());
		System.err.println(result.getResponse().getIncludedUrl());
		System.err.println(result.getResponse().getStatus());
	}

	
		
	}

推荐几篇讲的不错的blog

http://www.cnblogs.com/0201zcr/p/5756642.html

http://www.cnblogs.com/xiadongqing/p/6211429.html

http://www.cnblogs.com/lyy-2016/p/6122144.html

http://www.cnblogs.com/kabi/p/5182102.html

http://www.cnblogs.com/wql025/p/5022310.html

http://blog.csdn.net/qianjiangqi/article/details/51087014

感谢以上作者.

 

 

转载于:https://my.oschina.net/mifans/blog/847962

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值