Junit4单元测试与mockmvc使用

上一篇博客已经完成了spring4.3与junit4.12的整合,如有疑问欢迎一起探讨学习。接下来将展示单元测试及mockmvc使用。
1、Controller层,在这也是我需要测试的层

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value="/")
public class DmController {

	@Autowired
	private DmService dmService; //服务接口
	//保存对象
	@RequestMapping(value="newdm.do",method = RequestMethod.POST)
	@ResponseBody
	public Object newdm(HttpSession session, DmDTO dmDTO) {  
		User user = getUser(session);
		String name = user.getName();
		if(name != null) {
			String result = dmService.save(dmDTO);
			return Message(String); //Message用于向前端返回数据对象
		}
		return null;
	}
	
	//get请求,用作页面跳转
	@RequestMapping(value="returnjsp.do",method=RequestMethod.GET)
	public String turnjsp(String id) {
		if(id.equals("one")) {
			return "/hello/one";
		}else {
			return "/hello/other";
		}		  
	}
}

DmService接口

public interface DmService {

	String save(DmDTO dmDTO);
}

DmServiceImpl实现类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service  //要记得加上这个注解,否则无法注入容器
public class DmServiceImpl implements DmService{

	@Autowired
	private DmDAO dmDAO;
	@Override
	public String save(DmDTO dmDTO) {
		if(dmDTO != null) {
			String result = dmDAO.save(dmDTO);
			return result;
		}
		return null;
	}
}

DmDAO接口

public interface DmDAO {

	String save(DmDTO dmDTO);
}

DmDAOImpl实现类

@Repository  //切记要加上该注解
public class DmDAOImpl implements DmDAO{
//真实的DAO实现类中应该是与数据库交互,这里为了方便就不写了
	@Override
	public String save(DmDTO dmDTO) {
		@Override
	public String save(DmDTO dmDTO) {
		if(dmDTO.getName().length()<5) {
			return "保存成功";
		}else {
			return "保存失败";
		}
	}
}

单元测试案例:

package cn.wolfcode;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.request.MockMvcResultHandlers.status;
import static org.springframework.test.web.servlet.request.MockMvcResultHandlers.view;

//测试类,需要继承前面整合好的BaseJunit
public class DmControllerTest extends BaseJunit{

	@Autowired
	DmController dmController;  //这里是直接从容器中拿出DmController这个bean,这个bean里使用到的依赖,比如DmService都
	@Test                       //已经注入到这个bean里,所以下面可以直接用这个bean来调用newdm方法进行测试
	public void testNewdm() { //注意:测试方法不能有返回值,也不能是有参函数
		DmDTO dmDTO =  new DmDTO();
		dmDTO.setName("hao"); //设置长度小于5,应该返回保存成功
		Message result =(Message) dmController.newdm(session,dmDTO); //这里使用到的session在BaseJunit中已经使用mockmvc构造了
		assertEquals("保存成功",result.getinfo());  //返回的对象获取里面的信息
	}
	
	//使用mockmc来测试,mockmvc主要是模拟页面对后台的访问,个人用的不是很习惯
	
	@Test                       
	public void testNewdmWithMockmvc() {
		DmDTO dmDTO =  new DmDTO();
		dmDTO.setName("hao"); 
		String requestJson = JSONObject.toJSONString(dmDTO);//mockmvc只能传string类型,对于这种对象类型的需要转成String类型
		mockMvc.perform(post("newdm.do")  //这里的mockMvc在BaseJunit已经定义好,请求url及请求方式,如果被测方法是get,这里对应的换成get即可
				.contentType(MediaType.APPLICATION_JSON) //接受的数据类型
				.content(requestJson)  //请求的数据内容
				.andExpect(status().isOk())  //断言返回的状态是正确的
				.session(session)    //session的方式,括号内的session也是BaseJunit里构造好的,可以根据自己的要求构造
				).andDo(print())   //结果处理器,用于在控台上打印结果  注意这里是需要静态引入
		         .andReturn();
	}
	
	@Test                       
	public void testTurnjsp() {
		mockMvc.perform(get("returnjsp.do"))  //使用get请求
		       .andExpect(status().isOk())
		       .andExpect(view().name("/hello/one")) //使用断言判断返回结果
			   .andDO(print())
			   .andReturn();
	}
}

这里也把之前的BaseJunit放出来吧

import javax.sql.DataSource;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.annotation.Rollback;
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.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class) //指定运行的测试类  该类在spring-test里,有时无法引入只能手工敲了
@ContextConfiguration(locations= {"classpath*:/applicationContext.xml"})//spring-test里的类,这个很重要,把配置文件里的内容加载到容器中
@WebAppConfiguration

@Transactional(transactionManager="transactionMananger") //这里的事务即是取applicationContext.xml的事务
@Rollback //默认为true 即事务回滚
public class BaseJunit {
	
	@Autowired
	protected WebApplicationContext wac;
	protected MockMvc mockMvc;
	protected MockHttpSession session;
	protected MockHttpServletRequest request;
	protected ModelMap map;

	@BeforeClass //Junit里的方法,在整个单元测试运行之前先运行,所以可以用于加载xml等文件操作,这里加载jndi.xml,
	public static void beforeClass() throws Exception{  //这样就解决了JNDI连接方式不启动tomcat无法连接数据库的问题
		ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath*:/jndi.xml");//加一个*会整个项目去找这个xml
		DataSource ds = (DataSource) app.getBean("dataSource"); //我们jndi.xml里配置的数据源id="dataSource"
		SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
		builder.bind("java:com/env/jdbc/hello",ds);//数据源与applicationContext.xml里的jndiName的value绑定
		builder.activate();
	}
	
	@Before //每个测试用例执行前都会执行一次
	public void setup() { //这里使用MockMvc构造各种session等,这个看个人需要吧
		this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
		this.session = new MockHttpSession();
		this.request = new MockHttpServletRequest();
		this.map = new ModelMap();
		User us = new User();     //用户实体类
		us.setUmname("lixiaolong");
		session.setAttribute("user",us);
	}
}

总结:
由于我们使用的是存储过程,存储过程里有commit,所以单元测试执行存储过程后是无法事务回滚的,这个问题我们后面会使用强大的Jmockit来完成。时间问题,后面再来补充经常遇到的报错问题,重点是后面的Jmockit强大的功能使用。
常见问题:1、org.springframework.beans.factory.NoSuchBeanDefinitionException:No bean named ‘dataSource’ is defind…
主要是没有加载到数据源,可以查看数据库配置是否有问题以及加载的jndi.xm路径是否正确了
2、java.lang.IllegalStateException:Failed to load ApplicationContext…
Caused by:org.springframework.beans.factory.UnsatisfiedDependencyException:Error creating bean with name ‘*’:Unsatisfied dependency expressed field ‘’; …
没加@Service/@Repository/@Controller这些注解的话就会报创建bean错误的异常。
3、java.lang.IllegalStateException:Failed to load ApplicationContext…
Caused by:java.lang.IllegalStateException:WebApplicationObjectSupport instance[ResourceHttpRequestHandler[locations=[class path resource[easyui/]],resolvers=…]]…
在测试类上加上@WebAppConfiguration注解即可,如BaseJunit里就加了该注解。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值