springboot+junit测试
参考视频:用Spring Boot编写RESTful API
参考链接:Spring Boot构建RESTful API与单元测试
参考链接:Junit自动单元测试以及测试覆盖率简单使用
一、junit断言
| 函数 | 作用 | 
|---|---|
| TestCase.assertTrue | 判断条件是否为真 | 
| TestCase.assertFalse | 判断条件是否为假 | 
| TestCase.assertEquals(val1,val2) | 判断val1是否和val2相等 | 
| TestCase.assertNotSame(val1,val2) | 判断val1是否和val2不相等 | 
| Assert.assertArrayEquals(array1,array2) | 判断两个数组相等 | 
| TestCase.fail(message) | 测试直接失败,抛出message信息 | 
注意:
assertTrue(val1 == val2) 是判断val1和val2是否是同一个实例
assertEquals(val1, val2) 是判断val1和val2值是否相等
Assert中有许多方法被淘汰了,这里建议多用TestCase
二、测试模块
- 测试模块:我们需要写测试代码的模块
 - 驱动模块:调用我们测试代码的模块
 - 桩模块 :模拟被测试的模块所调用的模块,而不是软件产品的组成的部分,这个桩模块本身不执行任何功能仅在被调用时返回静态值来模拟被调用模块的行为
 
桩模块简单实例(税收计算较复杂,可以先模仿一下,作为桩模块,这样就可以不影响被测模块的测试):

三、使用Mockito作为桩模块
我们在maven中加入Mockito和junit的依赖
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <scope>test</scope>
        </dependency>
数据库访问层studentDao如下(还未实现方法):
import org.springframework.stereotype.Repository;
import whu.xsy.swagger_use.entity.student;
import java.util.List;
@Repository
public interface studentDao {
    //TODO 从数据库获取所有学生信息
    List<student> getAll();
}
service层如下(调用studentDao):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import whu.xsy.swagger_use.dao.studentDao;
import whu.xsy.swagger_use.entity.student;
import java.util.List;
@Service
public class studentService {
    @Autowired
    studentDao studentDao;
    public List<student> getAll(){
        return studentDao.getAll();
    }
}
接下来开始设置桩模块并开始测试
此时数据库并没有数据,数据访问层dao也没写好,那么该如何测试service呢?
我们使用mockito在dao层调用特定方法时模拟返回数据,这样就可以不影响service层的测试,并且即使数据库发生变化(比如环境迁移),也不影响测试。
简而言之,就是mockito接管了dao层
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import whu.xsy.swagger_use.dao.studentDao;
import whu.xsy.swagger_use.entity.student;
import whu.xsy.swagger_use.service.studentService;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class SwaggerUseApplicationTests {
    @MockBean
    studentDao studentDao;
    @Autowired
    studentService studentService;
    @Test
    public void contextLoads(){} // 可用来检测springboot环境
    //测试studentService
    @Test
    public void testStudentService(){
        //模拟数据库中数据
        List<student> students= new ArrayList<>();
        students.add(new student(1,"xsy"));
        students.add(new student(2,"theory"));
        //由于 studentDao 的 getAll() 方法还没写好,所以使用 Mockito 做桩模块,模拟返回数据
        Mockito.when(studentDao.getAll()).thenReturn( students );
        //调用studentService.getAll()
        List<student> result = studentService.getAll();
        //断言
        TestCase.assertEquals(2,result.size());
        TestCase.assertEquals("xsy",result.get(0).getName());
    }
}
四、使用mockMvc测试web层
- 在test类上加上 
@AutoConfigureMockMvc注解 - 自动注入
MockMvc mockMvc; - 对studentController中增删改查接口进行测试
 
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import whu.xsy.swagger_use.entity.student;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/student")
@Api(value = "/student", tags = "学生模块") //标注在类上的
public class studentController {
    //模拟数据库
    private static List<student> students = new ArrayList<>();
    //初始化模拟数据库
    static{
        students.add(new student(1,"xsy"));
        students.add(new student(2,"theory"));
    }
    @GetMapping("")
    public List<student> getAll(){
        return students;
    }
    @PostMapping("")
    public boolean add(student student){
        return students.add(student);
    }
}
测试get方法(期望状态200,返回的json中含有xsy,打印返回的信息)
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@AutoConfigureMockMvc
public class SwaggerUseApplicationTests {
    @MockBean
    studentDao studentDao;
    @Autowired
    studentService studentService;
    @Autowired
    MockMvc mockMvc;
    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(new studentController()).build();
    }
    @Test
    public void testStudentController() throws Exception {
        RequestBuilder request = null;
        //查询所有学生
        request = get("/student/");
        mockMvc.perform(request)
                .andExpect(status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andExpect(content().string(Matchers.containsString("xsy")));
    }
}
测试通过,并且打印的信息如下:
MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /student/
       Parameters = {}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}
Handler:
             Type = whu.xsy.swagger_use.controller.studentController
           Method = whu.xsy.swagger_use.controller.studentController#getAll()
Async:
    Async started = false
     Async result = null
Resolved Exception:
             Type = null
ModelAndView:
        View name = null
             View = null
            Model = null
FlashMap:
       Attributes = null
MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = [{"id":1,"name":"xsy"},{"id":2,"name":"theory"}]
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
测试post方法:
本实例中展现了MockMvc如何上传数据和获取返回结果
测试方法与get类似
        request = post("/student/")
                .param("id","3")
                .param("name","ys");
        String result = mockMvc.perform(request)
                .andExpect(status().isOk())
                .andReturn().getResponse().getContentAsString();
        TestCase.assertEquals("true",result);
五、批量测试和测试覆盖率
我们将service的测试和controller的测试分开:

我们需要一次性运行所有的单元测试,则需要配置一次性运行whu.xsy.swagger_use中的所有test类(具体配置见Junit自动单元测试以及测试覆盖率简单使用)


然后点击run with coverage

就可以运行所有的测试文件,并且可以看到覆盖率

springboot+junit测试的更多相关文章
- SpringBoot Junit测试Controller
		
原文链接:https://blog.csdn.net/xiaolyuh123/article/details/73281522 import java.util.List; import org.sp ...
 - Springboot的日志管理&Springboot整合Junit测试&Springboot中AOP的使用
		
==============Springboot的日志管理============= springboot无需引入日志的包,springboot默认已经依赖了slf4j.logback.log4j等日 ...
 - springboot集成junit测试与javamail测试遇到的问题
		
1.springboot如何集成junit测试? 导入junit的jar包 使用下面注解: @RunWith()关于这个的解释看下这两篇文章: http://www.imooc.com/qadetai ...
 - springBoot中使用使用junit测试文件上传,以及文件下载接口编写
		
本篇文章将介绍如何使junit在springBoot中测试文件的上传,首先先阅读如何在springBoot中进行接口测试. 文件上传操作测试代码 import org.junit.Before; im ...
 - SpringBoot系列三:SpringBoot基本概念(统一父 pom 管理、SpringBoot 代码测试、启动注解分析、配置访问路径、使用内置对象、项目打包发布)
		
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.了解SpringBoot的基本概念 2.具体内容 在之前所建立的 SpringBoot 项目只是根据官方文档实现的一个基础程 ...
 - 0005SpringBoot中用Junit测试实体类中绑定yml中的值
		
1.编写SpringBoot的引导类 package springboot_test.springboot_test; import org.springframework.boot.SpringAp ...
 - 基于Springboot+Junit+Mockito做单元测试
		
前言 前面的两篇文章讨论过< 为什么要写单元测试,何时写,写多细 >和<单元测试规范>,这篇文章介绍如何使用Springboot+Junit+Mockito做单元测试,案例选取 ...
 - 写Junit测试时用Autowired注入的类实例始终为空怎么解?
		
踩坑半天多,终于在网上寻觅到了解决方案,特此分享一下. 重要前提:src/main/java下的根包名必须和src/test/main的根包名完全一致,否则就会发生死活不能注入的情况,要继续进行下面的 ...
 - 复利计算器(软件工程)及Junit测试———郭志豪
		
计算:1.本金为100万,利率或者投资回报率为3%,投资年限为30年,那么,30年后所获得的利息收入:按复利计算公式来计算就是:1,000,000×(1+3%)^30 客户提出: 2.如果按照单利计算 ...
 
随机推荐
- EM(最大期望)算法推导、GMM的应用与代码实现
			
EM算法是一种迭代算法,用于含有隐变量的概率模型参数的极大似然估计. 使用EM算法的原因 首先举李航老师<统计学习方法>中的例子来说明为什么要用EM算法估计含有隐变量的概率模型参数. 假设 ...
 - gitbub.com设置协作者提交代码步骤
			
1. 邀请协作者 点击settings 2. 等待协作者接受邀请 关注注册邮箱 3. 协作者生成公钥 一路回车即可 ssh-keygen -t rsa -b 4096 -C "公众号:九点半 ...
 - 并发编程之详解InheritableThreadLocal类原理
			
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 在Java并发编 ...
 - Python分支结构与流程控制
			
Python分支结构与流程控制 分支结构 if 语句 分支结构在任何编程语言中都是至关重要的一环,它最主要的目的是让计算机拥有像人一样的思想,能在不同的情况下做出不同的应对方案,所以if语句不管是在什 ...
 - day19__生成器,迭代器
			
一.列表解析 l1 = ['鸡蛋%s' % i for i in range(10) if i > 5] print(l1) # ['鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9'] 这种方 ...
 - git和github入门指南(6)
			
6.交作业的流程 以下内容是螺钉课堂在线就业班提交作业的要求,非螺钉课堂在线就业班学员不用学习 螺钉课堂作业全程采用git管理,希望在日常使用中,加深对git和github的理解 具体流程: 1.注册 ...
 - plsql启动报 Using filter for all users can lead to poor perform
			
首先,这个与Oracle配置无关,就是在使用pl/sql左侧树形目录时会看到非常多的和你当前工作无关的表,视图,序列等,导致打开速度慢. 解决办法:Tools-->Object browser ...
 - 洛谷 P3916 【图的遍历】
			
这道题绿题有点高了吧... 我一开始的思路就是一个暴力的遍历,用递归加一个记忆化,对于一个点不断的往下搜索,然后确定最大的,返回,给上面的节点.就在这个过程中,我们是搜到最大的数然后返回给上层的数,那 ...
 - java架构-一些设计上的基本常识
			
最近给团队新人讲了一些设计上的常识,可能会对其它的新人也有些帮助, 把暂时想到的几条,先记在这里. 1.API与SPI分离 框架或组件通常有两类客户,一个是使用者,一个是扩展者. API(Applic ...
 - 创建虚拟机和安装centos7 & install oracle
			
win7 x64位+VMware12+centos7 x64位+oracle 11g R2安装详解(一) 一.虚拟机安装oracle11g R2的安装环境: 1.win7 x64位 ...