SpringBoot使用Junit4单元测试
SpringBoot2.0笔记
本篇介绍Springboot单元测试的一些基本操作,有人说一个合格的程序员必须熟练使用单元测试,接下来我们一起在Springboot项目中整合Junit4单元测试。
本文使用idea工具构建Springboot2.0+SpringMvc+Thymeleaf+SpringDataJPA+MySql项目
GitHub地址:https://github.com/jwam/springbootJunit4.git
一、IDEA下载并安装Junit插件
点击file-settings,如图按照顺序操作即可,我这里已经安装过了所以最后一步不会显示install按钮。
二、引入关键依赖,完整pom文末给出
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-test</artifactId>
-
<scope>test</scope>
-
</dependency>
-
<dependency>
-
<groupId>junit</groupId>
-
<artifactId>junit</artifactId>
-
<version>4.12</version>
-
<!--<scope>test</scope>-->
-
</dependency>
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-test</artifactId>
-
<version>5.0.4.RELEASE</version>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-test</artifactId>
-
<version>2.0.0.RELEASE</version>
-
</dependency>
三、新建UserController.java作为被测试类
-
package com.springboot.demo.controller;
-
-
import com.springboot.demo.base.controller.BaseController;
-
import com.springboot.demo.base.utils.StateParameter;
-
import com.springboot.demo.entity.User;
-
import com.springboot.demo.service.UserService;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.ui.ModelMap;
-
import org.springframework.util.StringUtils;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RequestMethod;
-
import org.springframework.web.bind.annotation.ResponseBody;
-
-
import javax.servlet.http.HttpServletRequest;
-
import java.util.Date;
-
import java.util.List;
-
-
/**
-
* @ClassName: UserController
-
* @Auther: zhangyingqi
-
* @Date: 2018/8/27 17:30
-
* @Description:
-
*/
-
@Controller
-
@RequestMapping(value="/user")
-
public class UserController extends BaseController{
-
@Autowired
-
UserService userService;
-
-
/**
-
* @auther: zhangyingqi
-
* @date: 17:37 2018/8/27
-
* @param: [request, user]
-
* @return: org.springframework.ui.ModelMap
-
* @Description: 用户保存&更新
-
*/
-
@RequestMapping(value="/add", method = RequestMethod.POST)
-
@ResponseBody
-
public ModelMap add(User user){
-
try {
-
if(StringUtils.isEmpty(user.getId())){
-
user.setId(getUuid());
-
}else{
-
user.setUpdateDate(new Date());
-
}
-
userService.save(user);
-
logger.info("保存成功");
-
return getModelMap(StateParameter.SUCCESS, user, "保存成功");
-
} catch (Exception e) {
-
e.printStackTrace();
-
return getModelMap(StateParameter.FAULT, null, "保存失败");
-
}
-
}
-
-
/**
-
* @auther: zhangyingqi
-
* @date: 17:47 2018/8/27
-
* @param: [id]
-
* @return: org.springframework.ui.ModelMap
-
* @Description: 删除用户
-
*/
-
@RequestMapping(value="/delete", method = RequestMethod.GET)
-
@ResponseBody
-
public ModelMap delete(String id){
-
try {
-
User user = userService.findById(id);
-
if(user==null){
-
return getModelMap(StateParameter.FAULT, user, "找不到该用户");
-
}
-
userService.delete(user);
-
logger.info("删除成功");
-
return getModelMap(StateParameter.SUCCESS, null, "删除成功");
-
} catch (Exception e) {
-
e.printStackTrace();
-
return getModelMap(StateParameter.FAULT, null, "删除失败");
-
}
-
}
-
-
/**
-
* @auther: zhangyingqi
-
* @date: 17:47 2018/8/27
-
* @param: [request]
-
* @return: java.lang.String
-
* @Description: 查询用户列表
-
*/
-
@RequestMapping(value="/list")
-
public String view(HttpServletRequest request){
-
List<User> list = userService.findAll();
-
request.setAttribute("list", list);
-
logger.info("返回列表页面");
-
return "/demoPage/listPage";
-
}
-
-
}
UserController类中用到的其他依赖都可以去我文章开始提供的GitHub地址下载,其实看过我之前文章的人应该都知道,最简单的办法就是直接下载demo了,当然你也可以自己编写一个controller类,在本篇中并没有特别要求。
当然不能少了实体类User.java,父类前几篇文章我都有写过,demo里也有,节省文本这里不再给出。
-
package com.springboot.demo.entity;
-
-
import lombok.Data;
-
-
import javax.persistence.Column;
-
import javax.persistence.Entity;
-
import javax.persistence.Table;
-
-
/**
-
* @ClassName: User
-
* @Auther: zhangyingqi
-
* @Date: 2018/8/27 17:17
-
* @Description:
-
*/
-
@Entity
-
@Table(name = "user")
-
@Data
-
public class User extends BaseEntity{
-
@Column(name = "name", length = 100)
-
private String name;
-
-
@Column(name = "age")
-
private int age;
-
}
另外还需要list方法返回的实际页面,在项目template下demoPage下新建listPage.html
-
<!DOCTYPE html>
-
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
-
<head>
-
<meta charset="UTF-8">
-
<title>用户列表</title>
-
</head>
-
<body>
-
<div>
-
<table>
-
<thead>
-
<tr>
-
<th>用户名称</th>
-
<th>年龄</th>
-
<th>创建时间</th>
-
</tr>
-
</thead>
-
<tbody>
-
<tr th:if="${list !=null}" th:each="item : ${list}">
-
<td th:text="${item.name}"></td>
-
<td th:text="${item.age}"></td>
-
<td th:text="${#dates.format(item.create_date, 'yyyy-MM-dd')}"></td>
-
</tr>
-
</tbody>
-
</table>
-
</div>
-
</body>
-
</html>
四、生成单元测试类
在UserController中按住alt+insert键,如图选择将自动生成测试类。
这时Junit工具将自动生成一个test目录,在同路径下生成同类名+Test组合名称UserControllerTest.java类,这就是自动生成的测试类。
我们改造这个测试类的内容
首先在类名上加入注解@RunWith和@SpringBootTest,后者需指定springboot启动类
-
@RunWith(SpringRunner.class)
-
@SpringBootTest(classes = DemoApplication.class)
-
public class UserControllerTest {
-
-
}
然后引入MockMvc对象及WebApplicationContext上下文,如果涉及业务的测试内容还需引入其他依赖,@Before表示在测试方法执行之前执行会该方法,所以我们在这里实例化mockmvc对象,这样后面就可以操作他了。
-
@RunWith(SpringRunner.class)
-
@SpringBootTest(classes = DemoApplication.class)
-
public class UserControllerTest {
-
-
/**
-
* 模拟mvc测试对象
-
*/
-
private MockMvc mockMvc;
-
-
/**
-
* web项目上下文
-
*/
-
@Autowired
-
private WebApplicationContext webApplicationContext;
-
-
/**
-
* 业务数据接口
-
*/
-
@Autowired
-
private UserService userService;
-
-
/**
-
* 所有测试方法执行之前执行该方法
-
*/
-
@Before
-
public void before() {
-
//获取mockmvc对象实例
-
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
-
}
-
-
}
接下来我们编写测试代码,首先对UserController中的查询用户列表方法进行测试,方法头部需添加@Test注解,具体方法内容如下,使用MockMvcRequestBuilders模拟get请求,status接收返回状态,responseString接收返回的内容。Assert.assertEquals
为通用的判断测试执行结果方法,其中三个参数分别为:不一致时提示信息,预期得到结果,实际得到结果。
-
@Test
-
public void testPage() throws Exception {
-
MvcResult mvcResult = mockMvc
-
.perform(// 1
-
MockMvcRequestBuilders.get("/user/list") // 2
-
//.param("name","getList") // 3
-
)
-
.andReturn();// 4
-
-
int status = mvcResult.getResponse().getStatus(); // 5
-
String responseString = mvcResult.getResponse().getContentAsString(); // 6
-
-
Assert.assertEquals("请求错误", 200, status); // 7
-
Assert.assertEquals("返回结果不一致", "/demoPage/listPage", responseString); // 8
-
}
接下来执行这个单元测试模块,IDEA自动检测到这是一个测试方法,我们直接点击方法左边的启动按钮即可,因为我已经执行过并且测试未通过,所以显示红色,本来是绿色。
如果执行成功会提示success,我这里提供的这个测试方法执行后是报失败的,具体原因是在列表页面获取不到实体中的create_date字段
做如下修改,将create_date改为createDate即可,所以我们可以看到,测试页面时会去渲染方法返回的整个html页面,如果有语法错误将会报错,测试执行失败。
-
<tbody>
-
<tr th:if="${list !=null}" th:each="item : ${list}">
-
<td th:text="${item.name}"></td>
-
<td th:text="${item.age}"></td>
-
<td th:text="${#dates.format(item.create_date, 'yyyy-MM-dd')}"></td>
-
</tr>
-
</tbody>
再次启动测试单元测试不再报错,但是依旧执行失败,提示“返回结果不一致”,我们点击结果对比发现返回结果有差异,所以未达到期望,直接返回了不一致时的提示信息,因此我们在测试返回页面时只需执行Assert.assertEquals("请求错误", 200, status); 即可,不必再判断返回期望。
注释掉返回结果预期判断之后执行测试成功。
那么返回结果预期判断怎么用呢,我们看下面的第二个测试删除用户方法,param可以添加传递的参数,预期结果为删除成功,我这里模拟了删除成功后的返回json数据,实际应用中可根据情况设定。
可以看到后台打印删除成功,同时单元测试执行通过。
本篇我通过Junit4单元测试对springboot项目的controller类进行测试,掌握基本的单元测试在springboot中整合的使用方法。
下面给出完整的pom包,推荐大家直接下载文首给出的demo,可以直接运行,方便又快捷。
-
<?xml version="1.0" encoding="UTF-8"?>
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0</modelVersion>
-
-
<groupId>com.springboot</groupId>
-
<artifactId>springbootJunit4</artifactId>
-
<version>0.0.1-SNAPSHOT</version>
-
<packaging>war</packaging>
-
-
<name>springbootJunit4</name>
-
<description>Demo project for Spring Boot</description>
-
-
<parent>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-parent</artifactId>
-
<version>2.0.4.RELEASE</version>
-
<relativePath/> <!-- lookup parent from repository -->
-
</parent>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-
<java.version>1.8</java.version>
-
</properties>
-
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-tomcat</artifactId>
-
<!--<scope>provided</scope>-->
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-data-jpa</artifactId>
-
<exclusions>
-
<exclusion>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-entitymanager</artifactId>
-
</exclusion>
-
<exclusion>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-core</artifactId>
-
</exclusion>
-
</exclusions>
-
</dependency>
-
<dependency>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-core</artifactId>
-
<version>5.2.10.Final</version>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-data-redis</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-mail</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-thymeleaf</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-web</artifactId>
-
</dependency>
-
-
<dependency>
-
<groupId>mysql</groupId>
-
<artifactId>mysql-connector-java</artifactId>
-
<scope>runtime</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.projectlombok</groupId>
-
<artifactId>lombok</artifactId>
-
<optional>true</optional>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-test</artifactId>
-
<scope>test</scope>
-
</dependency>
-
<dependency>
-
<groupId>junit</groupId>
-
<artifactId>junit</artifactId>
-
<version>4.12</version>
-
<!--<scope>test</scope>-->
-
</dependency>
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-test</artifactId>
-
<version>5.0.4.RELEASE</version>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-test</artifactId>
-
<version>2.0.0.RELEASE</version>
-
</dependency>
-
</dependencies>
-
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-maven-plugin</artifactId>
-
</plugin>
-
</plugins>
-
</build>
-
-
-
</project>
全文完,2018/8/30
原文地址:https://blog.csdn.net/zhulier1124/article/details/82228831
SpringBoot使用Junit4单元测试的更多相关文章
- JUnit4 单元测试
一. 题目简介 这次的单元测试我作了一个基本运算的程序,该程序实现了加,减,乘,除,平方,倒数的运算,该程序进行测试比较的简单,对于初步接触JUnit的我来说测试起来也比较容易理解. 二.源码的git ...
- springboot Service层单元测试
两个实现类实现同一个Service接口 public interface CustomUrlService { List<ShopMetrics> getShopMetrics(); } ...
- 【快学springboot】在springboot中写单元测试[Happyjava]
前言 很多公司都有写单元测试的硬性要求,在提交代码的时候,如果单测通不过或者说单元测试各种覆盖率不达标,会被拒绝合并代码.写单元测试,也是保证代码质量的一种方式. junit单元测试 相信绝大多数的J ...
- 【快学springboot】在springboot中写单元测试
前言 很多公司都有写单元测试的硬性要求,在提交代码的时候,如果单测通不过或者说单元测试各种覆盖率不达标,会被拒绝合并代码.写单元测试,也是保证代码质量的一种方式. junit单元测试 相信绝大多数的J ...
- springboot+mybatis整合(单元测试,异常处理,日志管理,AOP)
我用的事IDEA,jdk版本是1.7.新建项目的时候这个地方的选择需要注意一下,springboot版本是1.5的,否则不支持1.7的jdk pom.xml <dependency> &l ...
- spring-boot 速成(11) - 单元测试
一.添加依赖项: testCompile 'org.springframework.boot:spring-boot-starter-test:1.5.2.RELEASE' 二.单元测试代码示例 im ...
- 【SpringBoot】SpringBoot配置与单元测试(二)
SpringBoot项目创建参考[SpringBoot]SpringBoot快速入门(一) 本文介绍SpringBoot项目的POM文件.配置与单元测试 POM文件 1.SpringBoot的pom文 ...
- Junit4单元测试
在Eclipse中使用JUnit4进行单元测试(初级篇) 在Eclipse中使用JUnit4进行单元测试(中级篇) 在Eclipse中使用JUnit4进行单元测试(高级篇)
- JUnit4单元测试基础篇
引言 JUnit作为Java语言的测试框架,在测试驱动开发(TDD)下扮演重要的角色.众所周知,无论开发大型项目还是一般的小型项目, 单元测试都至关重要.单元测试为软件可发测试维护提供了很大的便利.J ...
随机推荐
- 01_5_SERVLET为什么有2个init方法
01_5_SERVLET为什么有2个init方法 1. 在web.xml配置初始化参数 <servlet> <servlet-name>TestInitServlet</ ...
- 数据结构C语言实现系列——线性表(单向链表)
#include <stdio.h> #include <stdlib.h> #define NN 12 #define MM 20 typedef int elemType ...
- 【贪心】bzoj1592: [Usaco2008 Feb]Making the Grade 路面修整
贪心的经典套路:替换思想:有点抽象 Description FJ打算好好修一下农场中某条凹凸不平的土路.按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也 就是说,高度上升与高度下降的路段不能 ...
- MySQL左右连接查询中的NULL的数据筛选问题
这里使用左连接为例子,对于左连接是将左边表的数据显示,右边表中如果没有对应的数据则使用null填充. game表: game_type表: SELECT g.name,g.type_id,t.type ...
- MAC系统里安装 Python
首先MAC系统自带Python2.6/2.7.这是因为有些系统文件需要.但是对于我来说,我需要用到Python3,所以需要自己下载安装.这时候,就有一个非常强大的软件 Homebrew.(安装方法见官 ...
- json.dumps ensure_ascii 方法
在使用json.dumps时要注意一个问题 import json print (json.dumps('中国')) "\u4e2d\u56fd" 输出的会是 '中国' 中 ...
- Seven Puzzle Aizu - 0121 (搜索)
7 パズル ime limit1000 ms Memory limit131072 kB OSLinux Source3rd PC Koshien, Final 7 パズルは 8 つの正方形のカードと ...
- poj-3278 catch that cow(搜索题)
题目描述: Farmer John has been informed of the location of a fugitive cow and wants to catch her immedia ...
- CentOS 7.X 中systemctl命令用法详解
systemctl是RHEL 7 的服务管理工具中主要的工具,它融合之前service和chkconfig的功能于一体.可以使用它永久性或只在当前会话中启用/禁用服务,下面来看CentOS 7.X 中 ...
- 水题:UVa133-The Dole Queue
The Dole Queue Time limit 3000 ms Description In a serious attempt to downsize (reduce) the dole que ...