参考视频:用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层

  1. 在test类上加上 @AutoConfigureMockMvc注解
  2. 自动注入MockMvc mockMvc;
  3. 对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测试的更多相关文章

  1. SpringBoot Junit测试Controller

    原文链接:https://blog.csdn.net/xiaolyuh123/article/details/73281522 import java.util.List; import org.sp ...

  2. Springboot的日志管理&Springboot整合Junit测试&Springboot中AOP的使用

    ==============Springboot的日志管理============= springboot无需引入日志的包,springboot默认已经依赖了slf4j.logback.log4j等日 ...

  3. springboot集成junit测试与javamail测试遇到的问题

    1.springboot如何集成junit测试? 导入junit的jar包 使用下面注解: @RunWith()关于这个的解释看下这两篇文章: http://www.imooc.com/qadetai ...

  4. springBoot中使用使用junit测试文件上传,以及文件下载接口编写

    本篇文章将介绍如何使junit在springBoot中测试文件的上传,首先先阅读如何在springBoot中进行接口测试. 文件上传操作测试代码 import org.junit.Before; im ...

  5. SpringBoot系列三:SpringBoot基本概念(统一父 pom 管理、SpringBoot 代码测试、启动注解分析、配置访问路径、使用内置对象、项目打包发布)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.了解SpringBoot的基本概念 2.具体内容 在之前所建立的 SpringBoot 项目只是根据官方文档实现的一个基础程 ...

  6. 0005SpringBoot中用Junit测试实体类中绑定yml中的值

    1.编写SpringBoot的引导类 package springboot_test.springboot_test; import org.springframework.boot.SpringAp ...

  7. 基于Springboot+Junit+Mockito做单元测试

    前言 前面的两篇文章讨论过< 为什么要写单元测试,何时写,写多细 >和<单元测试规范>,这篇文章介绍如何使用Springboot+Junit+Mockito做单元测试,案例选取 ...

  8. 写Junit测试时用Autowired注入的类实例始终为空怎么解?

    踩坑半天多,终于在网上寻觅到了解决方案,特此分享一下. 重要前提:src/main/java下的根包名必须和src/test/main的根包名完全一致,否则就会发生死活不能注入的情况,要继续进行下面的 ...

  9. 复利计算器(软件工程)及Junit测试———郭志豪

    计算:1.本金为100万,利率或者投资回报率为3%,投资年限为30年,那么,30年后所获得的利息收入:按复利计算公式来计算就是:1,000,000×(1+3%)^30 客户提出: 2.如果按照单利计算 ...

随机推荐

  1. 【转】Windows下PATH等环境变量详解

    [转]“肖凡的专栏” 博客,请务必保留此出处http://legend2011.blog.51cto.com/3018495/553255 在学习JAVA的过程中,涉及到多个环境变量(environm ...

  2. C#数据结构与算法系列(十):中缀表达式转后缀表达式

    1.具体步骤 1)初始化两个栈:运算符栈s1和储存中间结果的栈s2:2)从左至右扫描中缀表达式:3)遇到操作数时,将其压s2:4)遇到运算符时,比较其与s1栈顶运算符的优先级:     (1)如果s1 ...

  3. Perl入门(一)Perl的基本类型及运算符

    在学习Perl的基础之前,还是希望大家有空去看以下Perl的简介.百度百科 一.Perl的基本类型 Per的基本类型分为两种:数值型和字符串型. 数值型可细分为 整数型.如123. 浮点型.如123. ...

  4. Python变量与基本数据类型

    Python变量与基本数据类型 前言 好了,从本章开始将正式进入Python的学习阶段.本章主要介绍的是Python变量与基本数据类型的认识,这些都是最基本的知识并且必须要牢靠掌握在心中. 注释 学习 ...

  5. JavaScript基础Curry化(021)

    时候我们希望函数可以分步接受参数,并在所有参数都到位后得到执行结果.为了实现这种机制,我们先了解函数在Javascript中的应用过程: 1. 函数的“应用”(Function Application ...

  6. 浅谈pyautogui模块

    pyautogui模块 PyAutoGUI--让所有GUI都自动化 安装代码: pip install pyautogui 目的 PyAutoGUI是一个纯Python的GUI自动化工具,其目的是可以 ...

  7. Spring Security(四) —— 核心过滤器源码分析

    摘要: 原创出处 https://www.cnkirito.moe/spring-security-4/ 「老徐」欢迎转载,保留摘要,谢谢! 4 过滤器详解 前面的部分,我们关注了Spring Sec ...

  8. 阿里云centos7安装redis全过程记录

    Redis下载地址:https://redis.io/download(这个连接可能得翻墙查看,但是在centos7服务器上安装过程不需要翻墙,我查看了最新的是redis-4.0.9.tar.gz ) ...

  9. CSS选择器整理以及优先级介绍

    一.基础选择器 选择器 名称 描述 兼容性 * 通配选择器 选择所有的元素 ie6+ E 元素选择器 选择指定的元素 ie6+ #idName id选择器 选择id属性等于idName的元素 ie6+ ...

  10. unity spine 对翻转和大小的控制

    spine-unity怎么决定我的Spine模型的大小? Spine使用 1像素:1单位.意思是,如果你只是包含图像在你的骨架中,并且没有任何旋转和缩放,在Spine中该图像的1个像素就对应1个单位高 ...