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文末给出


  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-test</artifactId>
  4. <scope>test</scope>
  5. </dependency>
  6. <dependency>
  7. <groupId>junit</groupId>
  8. <artifactId>junit</artifactId>
  9. <version>4.12</version>
  10. <!--<scope>test</scope>-->
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework</groupId>
  14. <artifactId>spring-test</artifactId>
  15. <version>5.0.4.RELEASE</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-test</artifactId>
  20. <version>2.0.0.RELEASE</version>
  21. </dependency>

三、新建UserController.java作为被测试类


  1. package com.springboot.demo.controller;
  2. import com.springboot.demo.base.controller.BaseController;
  3. import com.springboot.demo.base.utils.StateParameter;
  4. import com.springboot.demo.entity.User;
  5. import com.springboot.demo.service.UserService;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.ui.ModelMap;
  9. import org.springframework.util.StringUtils;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RequestMethod;
  12. import org.springframework.web.bind.annotation.ResponseBody;
  13. import javax.servlet.http.HttpServletRequest;
  14. import java.util.Date;
  15. import java.util.List;
  16. /**
  17. * @ClassName: UserController
  18. * @Auther: zhangyingqi
  19. * @Date: 2018/8/27 17:30
  20. * @Description:
  21. */
  22. @Controller
  23. @RequestMapping(value="/user")
  24. public class UserController extends BaseController{
  25. @Autowired
  26. UserService userService;
  27. /**
  28. * @auther: zhangyingqi
  29. * @date: 17:37 2018/8/27
  30. * @param: [request, user]
  31. * @return: org.springframework.ui.ModelMap
  32. * @Description: 用户保存&更新
  33. */
  34. @RequestMapping(value="/add", method = RequestMethod.POST)
  35. @ResponseBody
  36. public ModelMap add(User user){
  37. try {
  38. if(StringUtils.isEmpty(user.getId())){
  39. user.setId(getUuid());
  40. }else{
  41. user.setUpdateDate(new Date());
  42. }
  43. userService.save(user);
  44. logger.info("保存成功");
  45. return getModelMap(StateParameter.SUCCESS, user, "保存成功");
  46. } catch (Exception e) {
  47. e.printStackTrace();
  48. return getModelMap(StateParameter.FAULT, null, "保存失败");
  49. }
  50. }
  51. /**
  52. * @auther: zhangyingqi
  53. * @date: 17:47 2018/8/27
  54. * @param: [id]
  55. * @return: org.springframework.ui.ModelMap
  56. * @Description: 删除用户
  57. */
  58. @RequestMapping(value="/delete", method = RequestMethod.GET)
  59. @ResponseBody
  60. public ModelMap delete(String id){
  61. try {
  62. User user = userService.findById(id);
  63. if(user==null){
  64. return getModelMap(StateParameter.FAULT, user, "找不到该用户");
  65. }
  66. userService.delete(user);
  67. logger.info("删除成功");
  68. return getModelMap(StateParameter.SUCCESS, null, "删除成功");
  69. } catch (Exception e) {
  70. e.printStackTrace();
  71. return getModelMap(StateParameter.FAULT, null, "删除失败");
  72. }
  73. }
  74. /**
  75. * @auther: zhangyingqi
  76. * @date: 17:47 2018/8/27
  77. * @param: [request]
  78. * @return: java.lang.String
  79. * @Description: 查询用户列表
  80. */
  81. @RequestMapping(value="/list")
  82. public String view(HttpServletRequest request){
  83. List<User> list = userService.findAll();
  84. request.setAttribute("list", list);
  85. logger.info("返回列表页面");
  86. return "/demoPage/listPage";
  87. }
  88. }

UserController类中用到的其他依赖都可以去我文章开始提供的GitHub地址下载,其实看过我之前文章的人应该都知道,最简单的办法就是直接下载demo了,当然你也可以自己编写一个controller类,在本篇中并没有特别要求。

当然不能少了实体类User.java,父类前几篇文章我都有写过,demo里也有,节省文本这里不再给出。


  1. package com.springboot.demo.entity;
  2. import lombok.Data;
  3. import javax.persistence.Column;
  4. import javax.persistence.Entity;
  5. import javax.persistence.Table;
  6. /**
  7. * @ClassName: User
  8. * @Auther: zhangyingqi
  9. * @Date: 2018/8/27 17:17
  10. * @Description:
  11. */
  12. @Entity
  13. @Table(name = "user")
  14. @Data
  15. public class User extends BaseEntity{
  16. @Column(name = "name", length = 100)
  17. private String name;
  18. @Column(name = "age")
  19. private int age;
  20. }

另外还需要list方法返回的实际页面,在项目template下demoPage下新建listPage.html


  1. <!DOCTYPE html>
  2. <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>用户列表</title>
  6. </head>
  7. <body>
  8. <div>
  9. <table>
  10. <thead>
  11. <tr>
  12. <th>用户名称</th>
  13. <th>年龄</th>
  14. <th>创建时间</th>
  15. </tr>
  16. </thead>
  17. <tbody>
  18. <tr th:if="${list !=null}" th:each="item : ${list}">
  19. <td th:text="${item.name}"></td>
  20. <td th:text="${item.age}"></td>
  21. <td th:text="${#dates.format(item.create_date, 'yyyy-MM-dd')}"></td>
  22. </tr>
  23. </tbody>
  24. </table>
  25. </div>
  26. </body>
  27. </html>

四、生成单元测试类

在UserController中按住alt+insert键,如图选择将自动生成测试类。

这时Junit工具将自动生成一个test目录,在同路径下生成同类名+Test组合名称UserControllerTest.java类,这就是自动生成的测试类。

我们改造这个测试类的内容

首先在类名上加入注解@RunWith和@SpringBootTest,后者需指定springboot启动类


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = DemoApplication.class)
  3. public class UserControllerTest {
  4. }

然后引入MockMvc对象及WebApplicationContext上下文,如果涉及业务的测试内容还需引入其他依赖,@Before表示在测试方法执行之前执行会该方法,所以我们在这里实例化mockmvc对象,这样后面就可以操作他了。


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = DemoApplication.class)
  3. public class UserControllerTest {
  4. /**
  5. * 模拟mvc测试对象
  6. */
  7. private MockMvc mockMvc;
  8. /**
  9. * web项目上下文
  10. */
  11. @Autowired
  12. private WebApplicationContext webApplicationContext;
  13. /**
  14. * 业务数据接口
  15. */
  16. @Autowired
  17. private UserService userService;
  18. /**
  19. * 所有测试方法执行之前执行该方法
  20. */
  21. @Before
  22. public void before() {
  23. //获取mockmvc对象实例
  24. mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
  25. }
  26. }

接下来我们编写测试代码,首先对UserController中的查询用户列表方法进行测试,方法头部需添加@Test注解,具体方法内容如下,使用MockMvcRequestBuilders模拟get请求,status接收返回状态,responseString接收返回的内容。Assert.assertEquals

为通用的判断测试执行结果方法,其中三个参数分别为:不一致时提示信息,预期得到结果,实际得到结果。


  1. @Test
  2. public void testPage() throws Exception {
  3. MvcResult mvcResult = mockMvc
  4. .perform(// 1
  5. MockMvcRequestBuilders.get("/user/list") // 2
  6. //.param("name","getList") // 3
  7. )
  8. .andReturn();// 4
  9. int status = mvcResult.getResponse().getStatus(); // 5
  10. String responseString = mvcResult.getResponse().getContentAsString(); // 6
  11. Assert.assertEquals("请求错误", 200, status); // 7
  12. Assert.assertEquals("返回结果不一致", "/demoPage/listPage", responseString); // 8
  13. }

接下来执行这个单元测试模块,IDEA自动检测到这是一个测试方法,我们直接点击方法左边的启动按钮即可,因为我已经执行过并且测试未通过,所以显示红色,本来是绿色。

如果执行成功会提示success,我这里提供的这个测试方法执行后是报失败的,具体原因是在列表页面获取不到实体中的create_date字段

做如下修改,将create_date改为createDate即可,所以我们可以看到,测试页面时会去渲染方法返回的整个html页面,如果有语法错误将会报错,测试执行失败。


  1. <tbody>
  2. <tr th:if="${list !=null}" th:each="item : ${list}">
  3. <td th:text="${item.name}"></td>
  4. <td th:text="${item.age}"></td>
  5. <td th:text="${#dates.format(item.create_date, 'yyyy-MM-dd')}"></td>
  6. </tr>
  7. </tbody>

再次启动测试单元测试不再报错,但是依旧执行失败,提示“返回结果不一致”,我们点击结果对比发现返回结果有差异,所以未达到期望,直接返回了不一致时的提示信息,因此我们在测试返回页面时只需执行Assert.assertEquals("请求错误", 200, status); 即可,不必再判断返回期望。

注释掉返回结果预期判断之后执行测试成功。

那么返回结果预期判断怎么用呢,我们看下面的第二个测试删除用户方法,param可以添加传递的参数,预期结果为删除成功,我这里模拟了删除成功后的返回json数据,实际应用中可根据情况设定。

可以看到后台打印删除成功,同时单元测试执行通过。

本篇我通过Junit4单元测试对springboot项目的controller类进行测试,掌握基本的单元测试在springboot中整合的使用方法。

下面给出完整的pom包,推荐大家直接下载文首给出的demo,可以直接运行,方便又快捷。


  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.springboot</groupId>
  6. <artifactId>springbootJunit4</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>war</packaging>
  9. <name>springbootJunit4</name>
  10. <description>Demo project for Spring Boot</description>
  11. <parent>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-parent</artifactId>
  14. <version>2.0.4.RELEASE</version>
  15. <relativePath/> <!-- lookup parent from repository -->
  16. </parent>
  17. <properties>
  18. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  19. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  20. <java.version>1.8</java.version>
  21. </properties>
  22. <dependencies>
  23. <dependency>
  24. <groupId>org.springframework.boot</groupId>
  25. <artifactId>spring-boot-starter-tomcat</artifactId>
  26. <!--<scope>provided</scope>-->
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-starter-data-jpa</artifactId>
  31. <exclusions>
  32. <exclusion>
  33. <groupId>org.hibernate</groupId>
  34. <artifactId>hibernate-entitymanager</artifactId>
  35. </exclusion>
  36. <exclusion>
  37. <groupId>org.hibernate</groupId>
  38. <artifactId>hibernate-core</artifactId>
  39. </exclusion>
  40. </exclusions>
  41. </dependency>
  42. <dependency>
  43. <groupId>org.hibernate</groupId>
  44. <artifactId>hibernate-core</artifactId>
  45. <version>5.2.10.Final</version>
  46. </dependency>
  47. <dependency>
  48. <groupId>org.springframework.boot</groupId>
  49. <artifactId>spring-boot-starter-data-redis</artifactId>
  50. </dependency>
  51. <dependency>
  52. <groupId>org.springframework.boot</groupId>
  53. <artifactId>spring-boot-starter-mail</artifactId>
  54. </dependency>
  55. <dependency>
  56. <groupId>org.springframework.boot</groupId>
  57. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  58. </dependency>
  59. <dependency>
  60. <groupId>org.springframework.boot</groupId>
  61. <artifactId>spring-boot-starter-web</artifactId>
  62. </dependency>
  63. <dependency>
  64. <groupId>mysql</groupId>
  65. <artifactId>mysql-connector-java</artifactId>
  66. <scope>runtime</scope>
  67. </dependency>
  68. <dependency>
  69. <groupId>org.projectlombok</groupId>
  70. <artifactId>lombok</artifactId>
  71. <optional>true</optional>
  72. </dependency>
  73. <dependency>
  74. <groupId>org.springframework.boot</groupId>
  75. <artifactId>spring-boot-starter-test</artifactId>
  76. <scope>test</scope>
  77. </dependency>
  78. <dependency>
  79. <groupId>junit</groupId>
  80. <artifactId>junit</artifactId>
  81. <version>4.12</version>
  82. <!--<scope>test</scope>-->
  83. </dependency>
  84. <dependency>
  85. <groupId>org.springframework</groupId>
  86. <artifactId>spring-test</artifactId>
  87. <version>5.0.4.RELEASE</version>
  88. </dependency>
  89. <dependency>
  90. <groupId>org.springframework.boot</groupId>
  91. <artifactId>spring-boot-test</artifactId>
  92. <version>2.0.0.RELEASE</version>
  93. </dependency>
  94. </dependencies>
  95. <build>
  96. <plugins>
  97. <plugin>
  98. <groupId>org.springframework.boot</groupId>
  99. <artifactId>spring-boot-maven-plugin</artifactId>
  100. </plugin>
  101. </plugins>
  102. </build>
  103. </project>

全文完,2018/8/30

原文地址:https://blog.csdn.net/zhulier1124/article/details/82228831

SpringBoot使用Junit4单元测试的更多相关文章

  1. JUnit4 单元测试

    一. 题目简介 这次的单元测试我作了一个基本运算的程序,该程序实现了加,减,乘,除,平方,倒数的运算,该程序进行测试比较的简单,对于初步接触JUnit的我来说测试起来也比较容易理解. 二.源码的git ...

  2. springboot Service层单元测试

    两个实现类实现同一个Service接口 public interface CustomUrlService { List<ShopMetrics> getShopMetrics(); } ...

  3. 【快学springboot】在springboot中写单元测试[Happyjava]

    前言 很多公司都有写单元测试的硬性要求,在提交代码的时候,如果单测通不过或者说单元测试各种覆盖率不达标,会被拒绝合并代码.写单元测试,也是保证代码质量的一种方式. junit单元测试 相信绝大多数的J ...

  4. 【快学springboot】在springboot中写单元测试

    前言 很多公司都有写单元测试的硬性要求,在提交代码的时候,如果单测通不过或者说单元测试各种覆盖率不达标,会被拒绝合并代码.写单元测试,也是保证代码质量的一种方式. junit单元测试 相信绝大多数的J ...

  5. springboot+mybatis整合(单元测试,异常处理,日志管理,AOP)

    我用的事IDEA,jdk版本是1.7.新建项目的时候这个地方的选择需要注意一下,springboot版本是1.5的,否则不支持1.7的jdk pom.xml <dependency> &l ...

  6. spring-boot 速成(11) - 单元测试

    一.添加依赖项: testCompile 'org.springframework.boot:spring-boot-starter-test:1.5.2.RELEASE' 二.单元测试代码示例 im ...

  7. 【SpringBoot】SpringBoot配置与单元测试(二)

    SpringBoot项目创建参考[SpringBoot]SpringBoot快速入门(一) 本文介绍SpringBoot项目的POM文件.配置与单元测试 POM文件 1.SpringBoot的pom文 ...

  8. Junit4单元测试

    在Eclipse中使用JUnit4进行单元测试(初级篇) 在Eclipse中使用JUnit4进行单元测试(中级篇) 在Eclipse中使用JUnit4进行单元测试(高级篇)

  9. JUnit4单元测试基础篇

    引言 JUnit作为Java语言的测试框架,在测试驱动开发(TDD)下扮演重要的角色.众所周知,无论开发大型项目还是一般的小型项目, 单元测试都至关重要.单元测试为软件可发测试维护提供了很大的便利.J ...

随机推荐

  1. spring5之SAXParseException:cvc-elt.1: 找不到元素 “beans” 的声明

    之前SSM项目一直报错,就是找不到错误  气啊 后来在网上找到了答案:燕来spring5之后就不再需要写版本号了

  2. MVC和MVP到底有什么区别呢?

    MVC和MVP到底有什么区别呢?   MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写 MVP 全称:Model-V ...

  3. 【0624作业】使用Scanner类输入并显示会员卡号

    package com.work0624; /** * 练习题 * 使用Scanner类输入并显示会员卡号 * @author L */ import java.util.Scanner; publi ...

  4. JDK安装及环境变量配置详解

    一.下载(Jdk 1.8 ) 1.下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151 ...

  5. HTML与XHTML区别

    1. html超文本标记语言,xhtml可扩展超文本标记语言,xhtml是将html作为xml的应用重新定义的一个标准. 2. xhtm比html的代码规则严格很多,例如'a < b'在xhtm ...

  6. 【转】如何在VC下检测当前存在的串口及串口热拔插

    当我们在用VS进行串口编程时,在打开串口前,经常想知道当前PC上存在多少个串口,哪些串口可用?哪些串口已经打开了,最好是在一个Combo Box中列表系统当前所有可用的串口以供选择,然而如何获取系统当 ...

  7. C++实现Singleton模式(effective c++ 04)

    阅读effective c++ 04 (31页) 提到的singleton设计模式.了解一下. 定义: 保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享. 应用场景: 比 ...

  8. JWT (JSON WEB Token)正确使用场景

    https://www.jianshu.com/p/af8360b83a9f 讲真,别再使用JWT了! ThoughtWorks中国 2017.08.16 08:51* 字数 2882 阅读 7154 ...

  9. Java-basic-4-数据类型

    Number类 装箱:将内置数据类型作为包装类对象使用:拆箱:相反 public class test{ public static void main(String args[]) { // box ...

  10. Java中的数据类型和引用

    JAVA数据类型分primitive数据类型和引用数据类型. Java中的primitive数据类型分为四类八种.primitive也不知道怎么翻译比较贴切, 暂且叫他基本数据类型吧, 其实直接从英文 ...