一、 单元测试的概念
-
单元测试(unit testing),是指检查和验证软件中最小的可测试单元。Java中单元测试的最小单元是类别。
-
单元测试是开发人员编写的一段代码,用于检查被测代码的小而清晰的功能是否正确。执行单元测试是为了证明这一点 段代码的行为是否符合我们的期望。
-
众所周知,通过spring initialize创建的Spring Boot项目会在Maven中自动携带大量starter依赖:
包含一个名字spring-boot-starter-test
本文围绕这种依赖展开依赖。
-
Spring Boot介绍单元测试非常简单,添加以下依赖性(即
spring-boot-starter-test
依赖):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
-
spring-boot-starter-test以下库:
spring-boot-starter-test
UML图:
二、单元测试的作用
我们在测试接触单元之前是怎么做的?一般有两种方法
在时间允许的情况下,编写单元测试是程序员对代码的自测,对自己的代码负责。
-
实现功能的保证或验证。
-
保护已实现的功能不被破坏。
三、Spring Boot引入的MockMvc的概念
-
什么是Mock?
在面向对象的程序设计中,模拟对象(英语:mock object)以可控的方式模拟真实对象行为的假对象。在编程过程中,程序是否达到预期结果通常通过模拟一些输入数据来验证。
-
为什么使用Mock对象?
使用模拟对象可以模拟复杂和真实的对象行为。如果真实对象不能用于单元测试,则可以用模拟对象代替。
-
MockMvc的概念
MockMvc是由spring-test提供包,实现正确Http请求模拟可以直接使用网络的形式转换为Controller调用,使测试速度快,不依赖网络环境。同时提供了一套验证工具,验证结果非常方便。
接口MockMvcBuilder,提供一个唯一的build该方法用于结构MockMvc。主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder。
-
MockMVC的基本步骤
(1) mockMvc.perform执行请求。(2) MockMvcRequestBuilders.get(“XXX)构建请求。(3) ResultActions.param添加请求传值 (4) ResultActions.accept()设置返回类型 (5) ResultActions.andExpect执行完成后添加断言。(6) ResultActions.andDo添加一个结果处理器,表示要对结果做些什么,比如在哪里使用print()输出整个响应结果信息。(7) ResultActions.andReturn表示执行完成后返回相应结果。
四、Service层单元测试
Spring Boot写在中单元测试类src/test/java在目录下,您可以手动或通过IDEA自动创建测试类,如下图所示:(注:点击并打开相应的代码界面,然后点击菜单栏Navigate)
按照第一步的方法,点击测试后出现对话框(如果已经有测试类需要测试,将被列出,也可以重新创建一个新的测试类),单击Create New Test…”会弹出可以选择是否生成对话框setUp以及要测试的成员方法:
图一
图二
至此Service创建层测试类,自动生成测试类src/test/java目录下,如下图:
Service层测试代码如下:
@SpringBootTest @RunWith(SpringRunner.class) public class XXXServiceTest { @Resource private XXXService XXXService; @Test public void conflictTime() { DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate start = LocalDate.parse("2020-10-26", dtf); LocalDate end = LocalDate.parse("2020-10-31", dtf); Integer integer = XXXService.ConflictTime("10000001", start, end); Assert.assertThat(integer, Matchers.notNullValue()assertThat后面介绍断言 } }
@SpringBootTest
:获取启动类,加载配置,寻找主配置启动类(被启动类) @SpringBootApplication 注解的)@RunWith(SpringRunner.class)
:让JUnit运行Spring的测试环境,获得Spring支持上下文的环境
五、Controller层单元测试
创建测试步骤见第四部分,此处略。
第四部分只针对Service层层测试,但我们也需要Controller层(API)做测试,这个时候用MockMvc它允许你在不启动项目的情况下测试这些接口
MockMvc实现了对Http请求模拟可以直接使用网络的形式转换为Controller调用可以使测试速度快,不依赖网络环境,提供一套验证工具,使要求验证统一方便。
Controller层部分的代码将分为三个代码块进行解释。如果有你不懂的代码,不要担心。您将在第五部分结尾总结答案。你应该坚持看到最后!
@SpringBootTest @RunWith(SpringRunner.class) @AutoConfigureMockMvc public class DfTaskRecordControllerTest { @Autowired private MockMvc mockMvc; @Before public void setUp() throws Exception { System.out.println("---------------start---------------"); save(); get(); System.out.println("================end================"); }
@SpringBootTest
>:获取启动类,加载配置,寻找主配置启动类(被启动类) @SpringBootApplication 注解的)
@RunWith(SpringRunner.class)
>:让JUnit运行Spring获得测试环境Spring支持上下文的环境@AutoConfigureMockMvc
:用于自动配置MockMvc,配置后MockMvc类可以直接注入,相当于new MockMvc@Before
:初始化方法 ,每种测试方法都必须执行一次
@Tes
@Transactional
@Rollback()
public void save() throws Exception {
String json"{……}";
//执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;
mockMvc.perform(MockMvcRequestBuilders
.post("/XXX/save")
.content(json.getBytes()) //传json参数
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.header("Authorization","Bearer ********-****-****-****-************")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(print());
}
@Transactional
:开启事务功能
@Rollback()
: 事务回滚,默认是true
@Test
public void get() throws Exception{
ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders
.get("/XXX/get")
.param("id", "**********")
.header("Authorization", "Bearer ********-****-****-****-************")
);
resultActions.andReturn().getResponse().setCharacterEncoding("UTF-8");
resultActions.andExpect(MockMvcResultMatchers.status().isOk()).andDo(print());
}
}
/get
运行结果如下:
1. mockMvc.perform
:执行一个请求
2. MockMvcRequestBuilders.get(“/XXX/get”)
:构造一个请求,Post请求使用.post方法
3. contentType(MediaType.APPLICATION_JSON_VALUE)
:代表发送端发送的数据格式是application/json;charset=UTF-8
4. accept(MediaType.APPLICATION_JSON)
:代表客户端希望接受的数据类型为application/json;charset=UTF-8
5. header(“Authorization”,“Bearer XXXX”)
:代表在报文头添加一些必须的信息,这里添加的是token
6. ResultActions.andExpect
:添加执行完成后的断言
7. ResultActions.andExpect(MockMvcResultMatchers.status().isOk())
:方法看请求的状态响应码是否为200如果不是则抛异常,测试不通过
8. ResultActions.andDo
:添加一个结果处理器,表示要对结果做点什么事情,比如此处使用print():输出整个响应结果信息
六、断言的概念
-
断言(assert),是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。
-
使用断言是判断一个函数或对象的一个方法所产生的结果是否符合你期望那个结果。
七、新断言assertThat使用
JUnit 4.4 结合 Hamcrest 提供了一个全新的断言语法——assertThat。程序员可以只使用 assertThat 一个断言语句,结合 Hamcrest 提供的匹配符,就可以表达全部的测试思想。
以前 JUnit 提供了很多的 assertion 语句,如:assertEquals,assertNotSame,assertFalse,assertTrue,assertNotNull,assertNull 等,现在有了 JUnit 4.4,一条 assertThat 即可以替代所有的 assertion 语句,这样可以在所有的单元测试中只使用一个断言方法,使得编写测试用例变得简单,代码风格变得统一,测试代码也更容易维护。
assertThat 使用了 Hamcrest 的 Matcher 匹配符,用户可以使用匹配符规定的匹配准则精确的指定一些想设定满足的条件,具有很强的易读性,而且使用起来更加灵活。
assertThat 不再像 assertEquals 那样,使用比较难懂的“谓宾主”语法模式(如:assertEquals(3, x);),相反,assertThat 使用了类似于“主谓宾”的易读语法模式(如:assertThat(x,is(3));),使得代码更加直观、易读。
assertThat( [value], [matcher statement] );
:接下来想要测试的变量值; :使用 Hamcrest 匹配符来表达的对前面变量所期望的值的声明,如果 value 值与 matcher statement 所表达的期望值相符,则测试成功,否则测试失败。
八、Postman与Spring Boot 单元测试的区别
-
Spring Boot的单元测试主要针对方法层面,可以测试Service层这类非对外暴露的接口的类中方法,并且可一次性批量测试多个方法、支持事务回滚。
-
Postman针对接口进行http测试,我平时这个比较多,创建的测试接口可保存、分类。
九、Postman基本用法
Postman是一款功能强大的网页调试与发送网页HTTP请求的工具。Postman能够发送任何类型的HTTP请求(GET, HEAD, POST,PUT..),附带任何数量的参数和HTTP headers。支持不同的认证机制(basic, digest,OAuth),接收到的响应语法高亮(HTML,JSON或XML)。
官方网站:
https://www.getpostman.com/apps
安装后,Postman是介样婶儿滴~~😊