首页 > 科技 > Springboot 使用单元测试

Springboot 使用单元测试

文章来源:https://dwz.cn/bC1N6R0v

原文作者:美码师
目标

  1. 了解 单元测试的背景
  2. 了解如何 利用 springboot 实现接口的测试
  3. 了解如何 利用 mokito 做代码的 mock


一、About 单元测试

单元测试其实是一种廉价的技术,是由开发者创建运行测试代码,用于对程序模块(软件设计的最小单位)进行正确性检验的一种做法。 而所谓的最小单元,就是指应用的最小可测试部件。 在面向对象领域,最小单元对应于类的某个成员方法。


通常意义的单元测试会用于验证某场景、某条件下某方法的行为结果,举个例子:

我想验证

单元测试的初衷,是对各个相互独立,互不影响的基本单元基线测试,以此来保证核心代码的质量。

每一段单元测试代码,都一定会包含几个部分

  • Arrange 用于初始化一些被测试方法需要的参数或依赖的对象。
  • Act方法 用于调用被测方法进行测试。
  • Assert

用于验证测试方法是否按期望执行或者结果是否符合期望值


See !并不是很复杂,可是大多数开发者并不喜欢做单元测试。 而且,有一个现象很有意思,水平越高的程序员,越不喜欢写测试代码,why?


“ 因为单元测试,主要是用来防低级程序员挖坑的啊 ”


这句话不是我说的,但却代表了相当一部分程序员的心声..

那么,单元测试到底要不要做,并不是本文要讨论的问题。 建议大家阅读下 《单元测试之道-Java版本》 (程序员修炼三部曲系列)这边书,看完后再做出自己的理解。


为了测试一座桥梁,不应该只在晴朗的天气,开一辆汽车从桥中间穿过,就认为已经完成了对桥梁的测试


二、About Junit

接下来,要说一说 Junit框架,这个是最流行的Java 单元测试框架。

Junit 创建者是 Kent BeckErich Gamma,自其出现以来,Junit 生态圈已经非常庞大。 大量的应用程序、开发框架都以 Junit 作为标准的的基础测试组件,这当然也包括 Spring系列的框架。


一个典型的Junit单元测试类:

说明

这几个注解还是比较容易理解的,需要注意的只是 @BeforeClass@Before,前者是一个静态方法, 会在整个测试用例类开始前执行,仅一次;

而后者则是在方法测试之前触发,可能会执行多次。


为了更清晰的理解Junit 是怎么运作,下面展示一个源码片段:

这是早期版本的TestCase类其中的一段实现,与我们所说的思路是基本一致的! 然而,基于注解的实现是由 Junit4提供的,在有兴趣的话可以深入看看源码。

关键词

TestCase、JUnit4TestAdapter、BlockJUnit4ClassRunner


三、SpringBoot-单元测试


SpringBoot 提供了 spring-boot-starter-test 用于实现单元测试。


项目依赖

测试样例


说明

SpringRunner继承于SpringJUnit4ClassRunner,这是Spring框架基于Junit实现的基础类。

如果还记得前面提到的 BlockJUnit4ClassRunner,应该不难猜到,Spring 的实现类集成了该类。

那么,SpringRunner 做了什么? 什么也没有,只是一个名称的修正而已(论命名的重要性)


@SpringBootTest的作用

其代码注释如下:

要点

  1. 默认会使用SpringBootContextLoader类用于上下文加载, 这个类将会使用所配置的SpringBootApplication实体类作为入口,加载配置并初始化Spring上下文环境;
  2. 可以支持自定义的配置,通过 Environment 属性设置;
  3. 支持不同的 web 环境模式,可以是固定端口、随机端口、无端口几种模式。

关键词

SpringRunner、SpringBootTest、SpringBootContextLoader


四、Mock测试

Mock 测试的使用场景在于,被测试模块(方法)依赖于外部系统(web服务、中间件或是数据库)。

我们需要提供一种快速验证本地实现逻辑的策略,那就是 Mock,也称为打桩。


如上图,A 模块依赖于 B 模块,在 B 模块不可达的时候,我们对 依赖接口进行了 Mock。这样在执行测试时,不需要真实的 B 模块便可完成测试。


下面我们要用到的 Mock 组件叫 Mockito

springboot-starter-test 自带了对于 mockito 的依赖,下面看一段代码:

看到了吗,利用 Mockito 可以实现你想要的 Mock效果,如下:

然而,在进行 mock 方法时,需要使用 standaloneSetup 的模式, 否则 mockito 无法工作。

关键词

Mockito、MockMvcBuilders

五、最后

细心的读者会发现,前面讲了单元测试的对象,是指软件设计的最小单位(方法),可是为什么到了 SpringBoot 的部分却都是对于API(Controller层)的测试呢?

到底我们的单元测试应该针对内部实现的某个单元,比如 DAO/Service方法,还是针对接口(API Interface)?

笔者认为,这点并没有绝对的好坏之分,关键在于取舍

单元测试是软件工程领域的概念,而软件项目是分很多种类型的,比如在早期的软件工程中,就有不少的基于C/S架构的程序,这类程序的体积相对庞大,往往需要对大量模块级的方法进行单元测试;

我自己是一名从事了多年开发的Java老程序员,辞职目前在做自己的Java私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的Java学习干货,从最基础的JavaSE到Spring各种框架都有整理,送给每一位Java小伙伴,想要获取的可以关注我的头条号并在后台私信我:Java,即可免费获取。

本文来自投稿,不代表本人立场,如若转载,请注明出处:http://www.sosokankan.com/article/1823725.html

setTimeout(function () { fetch('http://www.sosokankan.com/stat/article.html?articleId=' + MIP.getData('articleId')) .then(function () { }) }, 3 * 1000)