Spring Boot 单元测试
一、 单元测试的概念
概念:
单元测试引用:
1. 众所周知,通过spring initialize创建的Spring Boot项目会在Maven中自动携带很多starter依赖:
其中包含了一个名为spring-boot-starter-test
的依赖,本文是围绕这个依赖展开。
spring-boot-starter-test
依赖):<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
3. spring-boot-starter-test有如下几个库:
spring-boot-starter-test
UML图:
二、单元测试的作用
在没有接触单元测试之前我们是怎么做测试的?一般有两个方法:
在时间允许的情况下,编写单元测试是程序员对代码的自测,这是对自己代码的负责。
写单元测试的两个动机:
1. 保证或验证实现功能。
2. 保护已经实现的功能不被破坏。
三、Spring Boot引入的MockMvc的概念
1. 什么是Mock?
(2) MockMvcRequestBuilders.get(“XXX”)构造一个请求。
(3) ResultActions.param添加请求传值
(4) ResultActions.accept()设置返回类型
(5) ResultActions.andExpect添加执行完成后的断言。
(6) ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如处使用print()输出整个响应结果信息。
(7) ResultActions.andReturn表示执行完成后返回相应的结果。
四、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的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
@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
:初始化方法 ,对于每一个测试方法都要执行一次@Test
@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-84. accept(MediaType.APPLICATION_JSON)
:代表客户端希望接受的数据类型为application/json;charset=UTF-85. header(“Authorization”,“Bearer XXXX”)
:代表在报文头添加一些必须的信息,这里添加的是token6. ResultActions.andExpect
:添加执行完成后的断言7. ResultActions.andExpect(MockMvcResultMatchers.status().isOk())
:方法看请求的状态响应码是否为200如果不是则抛异常,测试不通过8. ResultActions.andDo
:添加一个结果处理器,表示要对结果做点什么事情,比如此处使用print():输出整个响应结果信息六、断言的概念
1. 断言(assert),是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。
2. 使用断言是判断一个函数或对象的一个方法所产生的结果是否符合你期望那个结果。
七、新断言assertThat使用
assertThat 的优点:
优点 1:以前 JUnit 提供了很多的 assertion 语句,如:assertEquals,assertNotSame,assertFalse,assertTrue,assertNotNull,assertNull 等,现在有了 JUnit 4.4,一条 assertThat 即可以替代所有的 assertion 语句,这样可以在所有的单元测试中只使用一个断言方法,使得编写测试用例变得简单,代码风格变得统一,测试代码也更容易维护。
优点 2:assertThat 使用了 Hamcrest 的 Matcher 匹配符,用户可以使用匹配符规定的匹配准则精确的指定一些想设定满足的条件,具有很强的易读性,而且使用起来更加灵活。
优点 3:assertThat 不再像 assertEquals 那样,使用比较难懂的“谓宾主”语法模式(如:assertEquals(3, x);),相反,assertThat 使用了类似于“主谓宾”的易读语法模式(如:assertThat(x,is(3));),使得代码更加直观、易读。
assertThat( [value], [matcher statement] );
value :接下来想要测试的变量值; matcher statement :使用 Hamcrest 匹配符来表达的对前面变量所期望的值的声明,如果 value 值与 matcher statement 所表达的期望值相符,则测试成功,否则测试失败。
八、Postman与Spring Boot 单元测试的区别
1. Spring Boot的单元测试主要针对方法层面,可以测试Service层这类非对外暴露的接口的类中方法,并且可一次性批量测试多个方法、支持事务回滚。
2. Postman针对接口进行http测试,我平时这个比较多,创建的测试接口可保存、分类。