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
