绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
Springboot 使用单元测试
2019-12-11 14:04:39

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

原文作者:美码师

目标

了解 单元测试的背景

了解如何 利用 springboot 实现接口的测试

了解如何 利用 mokito 做代码的 mock

一、About 单元测试

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

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

我想验证

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

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

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

Act方法 用于调用被测方法进行测试。

Assert 

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

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

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

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

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

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

二、About Junit

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

Junit 创建者是 Kent Beck 和 Erich 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的作用

其代码注释如下:

要点

默认会使用SpringBootContextLoader类用于上下文加载, 这个类将会使用所配置的SpringBootApplication实体类作为入口,加载配置并初始化Spring上下文环境;

可以支持自定义的配置,通过 Environment 属性设置;

支持不同的 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架构的程序,这类程序的体积相对庞大,往往需要对大量模块级的方法进行单元测试;

分享好友

分享这个小栈给你的朋友们,一起进步吧。

星说
创建时间:2019-11-28 12:45:43
作为炎黄子孙,我们有很多知识渊博的祖人,这个祖人指的是在各领域登峰造极的学者论说,我们跟随强大基因的路线,学习,深化自己的知识体系,优化环境。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • unnamed persona
    栈主

小栈成员

查看更多
  • 外星人6
  • supergirlxu
  • unnamed person1
  • daxuesheng
戳我,来吐槽~