SpringMVC的单体测试
目录
一.测试前梳理。
二.实例
1.一个简单的单体测试
(1).给spirng_demo1项目中引入jar包
(2).编写测试类。
(3).测试,点击运行:run as Junit Test
2.测试多个测试类
(1).再编写个测试类
(2).编写JUnit套件类,同时测试两个测试类
(3).点击运行
3.测试SpringMVC—业务层Service
(1).引入jar包
(2).分析要测试的组件
(3).编写测试类
(4).查看结果
4.测试SpringMVC—控制层Controller
(1).先看看这个UserController是啥情况
(2).编写测试类
(3).查看结果
相信不少人肯定听说过单元测试,那么单元测试和单体测试是不是一回事呢,我们得先得把这个搞明白。
先来看看他们的概念:
单元测试:是开发人员写好了一个简单的功能,从业务的角度来看就是完成了一个小功能我们去测试这个小功能。例如:我们编写好了一个登录功能或是一个用户信息展示功能,我们对这个小功能进行测试,就是单元测试。
单体测试:是开发人员编写好一个组件,从编程的角度来看就是完成了一小部分去测试这小部分。例如:我们在spingMVC项目中,编写好一个持久层组件,比如一个UserDao,我们对他进行测试,就是单体测试。
接下来我们开始学习这个单体测试,看看它是怎么测试springMVC的!
一.测试前梳理。
工具包:
JUnit包,用来单体测试。
HttpClient工具包,用来发送http请求和接收响应。
spring-test.jar包(基于JUnit4),专门用来测试SpringMVC。
注解:
@Test注解:标注要测试的方法,往往是测试的业务入口方法。
@Before注解:在执行被@Test标注的方法之前,先执行该方法(被@Before标注的方法)。
@After注解:在执行被@Test标注的方法之后,再执行该方法(被@After标注的方法)。
断言:
Assert:断言,一般比较期望结果和实际结果
二.实例
今天的实例是基于之前搭好的SpringMVC项目,大家可以看我前面写过的文章基于springMVC的前后端分离开发、Spring中的AOP、Spring事务管理这3个中任意一个搭好的SpringMVC都可以作为今天的基础。当然了,大家也可以自己搭建一个SpringMVC项目,在自己的搭建的项目上学习今天的单体测试。
1.一个简单的单体测试
(1).给spirng_demo1项目中引入jar包
有junit-5.0-20150111.191949-1.jar、hamcrest-core-1.3.rc2.jar。如下图:
(2).编写测试类。
在com.cdd.test包下,编写测试类JUnitDemo1,代码如下:
package com.cdd.test;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class JUnitDemo1 {
@Before
public void before(){
System.out.println("在要测试的方法之前执行");
}
@After
public void after(){
System.out.println("在测试方法之后执行");
}
@Test
public void test1(){
System.out.println("测试方法一");
}
@Test
public void test2(){
System.out.println("测试方法二");
String expected = "晴天";
String actual = "雨天";
Assert.assertEquals(expected, actual);
}
}
(3).测试,点击运行:run as Junit Test
a.查看控制台输出:
b.JUnit窗口:
当然了,只想要运行单个测试方法可以鼠标放在某个方法上,右键run as à Junit Test 来运行。那如果像JUnitDemo1这样的测试类有很多呢,我们测试时,要一个类一个类的去测试吗,当然不是的。请接着往下看。
2.测试多个测试类
这里要用到JUnit套件类,注解:
@RunWith(Suite.class) : 标注类事Junit套件类
@SuiteClasses :写要调用的测试类,用法如下
一个测试类:@SuiteClasses(TestClass1.class) //TestClass1是一个测试类
多个测试类:@SuiteClasses({TestClass1.class, TestClass2.class}) //TestClass2也是个测试类
(1).再编写个测试类
刚才已经编写了测试类JUnitDemo1,现在再com.cdd.test包下再编写个测试类JUnitDemo2,代码如下:
package com.cdd.test;
import org.junit.Test;
public class JUnitDemo2 {
@Test
public void say(){
System.out.println("good night!");
}
}
(2).编写JUnit套件类,同时测试两个测试类
在com.cdd.test包下,编写JUnitSuiteTest类,代码如下:
package com.cdd.test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class) //标注该类是个套件类,可以测试多个测试类
@SuiteClasses({JUnitDemo1.class, JUnitDemo2.class}) //要测试的两个测试类JUnitDemo1、JUnitDemo2
public class JUnitSuiteTest {
}
(3).点击运行
a.查看控制台输出:
b.查看JUnit窗口:
可以看出两个测试类都测试了,结果在意料之中。
3.测试SpringMVC—业务层Service
(1).引入jar包
在项目中引入spring-test.jar包,这里我们引入spring-test-5.0.8.RELEASE.jar,如果之前已经引入过,可省略这个步骤。
(2).分析要测试的组件
这里我们要测试该项目的登录功能的业务组件UserService,我们先来看下这个UserService是如何实现的,代码如下:
package com.cdd.serviceImpl;
import java.security.NoSuchAlgorithmException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.cdd.dao.UserDao;
import com.cdd.entity.DataResult;
import com.cdd.entity.User;
import com.cdd.service.UserService;
import com.cdd.util.FirstUtil;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public DataResult Login(String name, String pwd) {
System.out.println("正在service层");
DataResult dataResult = new DataResult();
//给密码进行md5加密
try {
pwd = FirstUtil.md5(pwd);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
Integer isExist = userDao.checkLogin(name, pwd);
if(isExist==null || isExist==0){
dataResult.setStatus(-1);
dataResult.setMsg("用户名或密码错误");
}else{
dataResult.setStatus(0);
dataResult.setMsg("登录成功");
}
// //构造一个数组下标越界异常
// int[] a = {1};
// System.out.println(a[2]);
return dataResult;
}
}
从上面的代码我们可以看出进行登录的话,要测试两个分支,分支1:用户名或密码输出的情况;分支2,:用户名和密码都正确,登录成功。接下来看我们如何测试。
(3).编写测试类
在com.cdd.test包下编写测试类UserServiceTest,我们正确的用户名:cdd,密码:1234,代码如下:
package com.cdd.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.cdd.entity.DataResult;
import com.cdd.service.UserService;
import com.cdd.serviceImpl.UserServiceImpl;
public class UserServiceTest {
private UserService userService;
@Before
public void init(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
userService = ac.getBean("userServiceImpl", UserService.class);
}
//测试用户名或密码输错的情况
@Test
public void test1(){
DataResult result = userService.Login("cdd", "12");
int status = result.getStatus(); //响应状态码
String msg = result.getMsg(); //响应消息
Assert.assertEquals(-1, result.getStatus()); //-1:用户名或密码错误,登录失败
Assert.assertEquals("用户名或密码错误",msg);
}
//测试用户名和密码都正确的情况
@Test
public void test2(){
DataResult result = userService.Login("cdd", "1234");
int status = result.getStatus(); //响应状态码
String msg = result.getMsg(); //响应消息
Assert.assertEquals(0, result.getStatus()); //0:用户名和密码都正确,登录成功
Assert.assertEquals("登录成功",msg);
}
}
(4).查看结果
JUnit窗口结果如下:
4.测试SpringMVC—控制层Controller
这里我们来测试登录功能的控制层组件UserController,有两注解我们需要看下,如下:
@RunWith:用于指定junit运行环境,是junit提供给其他框架测试环境接口扩展,为了便于使用spring的依赖注入,spring提供了org.springframework.test.context.junit4包下的SpringJUnit4ClassRunner作为Junit测试环境。
@ContextConfiguration:导入配置文件
(1).先看看这个UserController是啥情况
代码如下:
package com.cdd.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cdd.entity.DataResult;
import com.cdd.service.UserService;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login.do")
@ResponseBody
public DataResult login(@RequestParam(name="name",required=true) String name, @RequestParam(name="pwd",required=true) String pwd){
DataResult dataResult = userService.Login(name, pwd);
return dataResult;
}
}
(2).编写测试类
在com.cdd.test包下编程测试类UserControllerTest,我们正确的用户名:cdd,密码:1234,代码如下:
package com.cdd.test;
import javax.annotation.Resource;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
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.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.cdd.controller.UserController;
import com.cdd.entity.DataResult;
import com.fasterxml.jackson.databind.ObjectMapper;
@RunWith(SpringJUnit4ClassRunner.class) //指定运行环境
@ContextConfiguration(locations={"classpath:applicationContext.xml"}) //加载Spring容器配置文件
public class UserControllerTest {
@Resource
private UserController userController; //注入要测试的Controller组件
private MockMvc mockmvc; //模拟http请求
//构建MockMvc实例
@Before
public void init(){
mockmvc = MockMvcBuilders.standaloneSetup(userController).build();
}
//测试UserController,测试用户名和密码都正确,登录成功的情况
@Test
public void test() throws Exception{
//创建一个post请求
MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post("/user/login.do");
//给请求添加参数,"name":cdd,"pwd":1234
request.param("name", "cdd").param("pwd", "1234");
//发送并执行请求,获取响应结果
MvcResult result = mockmvc.perform(request).andReturn();
//获取响应内容并转成字符串
String content = result.getResponse().getContentAsString();
//打印下这个响应内容
System.out.println(content);
//为了使用断言,要将响应内容转成DataResult对象
ObjectMapper mapper = new ObjectMapper();
DataResult dataResult = mapper.readValue(content, DataResult.class);
//使用断言
Assert.assertEquals(0, dataResult.getStatus()); //测试响应状态
Assert.assertEquals("登录成功",dataResult.getMsg());
}
}
(3).查看结果
a.查看控制台
响应内容打印出来了:
b.查看JUnit窗口
测试通过:
这个测试Controller层组件就完成了,至于测试另一个情况:用户名或密码错误,大家可以自己去加个测试方法实现,到这里我们的单体测试就说完了。