使用Spock框架进行单元测试

使用Spock框架进行单元测试 - OPEN 开发经验库
http://www.open-open.com/lib/view/open1439793373083.html
很多人一谈到单元测试就会想到xUnit框架。对于一些java新人来说,会用jUnit就是会写单元测试,高级点的会捣鼓一下testng,然后就认为自己掌握了单元测试。

2.2.单元测试的痛点
对于新人来说,很容易在编写单元测试的时候遇到这几类问题:
2.2.1.单元测试的资料不够全
这里不够全是相对于“编码”来说的。介绍如何编码、如何使用某个框架的书茫茫多,但是与编码同样重要的介绍单元测试的书却不多,翻来覆去好的也不多,并且都有一定年头了。(如果有这方面的好的资料,请推荐给我,多谢)
很多关于编程的书籍中并没有深入介绍如何进行单元测试,或者仅仅介绍了最基础的assert、jUnit里怎么定义一个测试函数之类,就没有然后了,给人的感觉是这样:
[图片上传中。。。(1)]
2.2.2.单元测试难以理解和维护
测试代码不像普通的应用程序一样有着很明确的作为“值”的输入和输出。举个例子,假如一个普通的函数要做下面这件事情:
接收一个user对象作为参数
调用dao层的update方法更新用户属性
返回true/false结果

那么,只需要在函数中声明一个参数、做一次调用、返回一个布尔值就可以了。但如果要对这个函数做一个“纯粹的”单元测试,那么它的输入和输出会有很多情况,比如其中一个测试是这样:
假设调用dao层的update方法会返回true。
程序去调用service层的update方法。
验证一下service是不是也返回了true。

无论是用什么样的单元测试框架,最后写出来的单元测试代码量也比业务代码只多不少,我在写代码过程中的经验值是:要在不作弊的情况下维持比较高的单元测试覆盖率,要有三倍于业务代码的单测代码。
更多的代码量,加上单测代码并不像业务代码那样直观,还有对单测代码可读性不重视的坏习惯,导致最终呈现出来的单测代码难以阅读,要维护更是难上加难。
同时,大部分单元测试的框架都有很强的代码侵入性。要理解单元测试,首先得学习他用的那个单元测试框架,这无形中又增加了单元测试理解和维护的难度。
2.2.3.单元测试难以去除依赖
就像之前说的,如果要写一个纯粹的、无依赖的单元测试往往很困难,比如依赖了数据库、或者依赖了文件系统、再或者依赖了其它模块。
所以很多人在写单元测试时选择依赖一部分资源,比如在本机启动一个数据库。这类所谓的“单元测试”往往很流行,但是对于多人合作的项目,这类测试却经常容易造成混乱。
比如说要在本地读个文件,或者连接某个数据库,其他修改代码的人(或者持续集成系统中)并没有这些东西,所以测试也都没法通过。最后大部分这类测试代码的下场都是用不了、也舍不得删,只好被注释掉,扔在那里。
随着开源项目逐渐发展,对外部资源的依赖问题开始可以通过一些测试辅助工具解决,比如使用内存型数据库H2代替连接实际的测试数据库,不过能替代的资源类型始终有限。
而实际工作过程中,还有一类难以处理的依赖问题:代码依赖。比如一个对象的方法中调用了其它对象的方法,其它对象又调用了更多对象,最后形成了一个无比巨大的调用树。
很多比较旧的描述单元测试的书里写了一些传统的办法,这类方法基本上是先对耦合的部分做模拟,再对结果部分做断言。例如可以通过继承来自己做一个假的stub对象,最终用assert的方式验证正确性。但是这相当于对于每种假设都要做一个假的对象,而且对结果进行验证也比较复杂:比如我要验证“更新”操作是否真的调用了dao层,那么要自己在stub对象里对调用进行计数,验证时再对计数进行断言,非常繁琐。
后来出现了一些mock框架,比如java的JMockit、EasyMock,或者Mockito。利用这类框架可以相对比较轻松的通过mock方式去做假设和验证,相对于之前的方式有了质的飞跃,但是即使用上这类框架,遇到复杂的业务代码往往也无能为力。
而往往新人的代码质量往往不高,尤其是对代码的拆分和逻辑的抽象还处于懵懂阶段。要对这类代码写单测,即使是工作了3,4年的高级码农也是一个挑战,对新人来说几乎是不可能完成的任务。这也让很多新人有了“写单测很难”的感觉。
所以在这里需要强调一个观点,写单元测试的难易程度跟代码的质量关系最大,并且是决定性的。项目里无论用了哪个测试框架都不能解决代码本身难以测试的问题,所以如果你遇到的是“我的代码里依赖的东西太多了所以写不出来单测”这样的问题的话,需要去看的是如何设计和重构代码,而不是这篇文章。


在Spring Boot项目中使用Spock框架 -
http://www.jianshu.com/p/f1e354d382cd
利用Spock、Mockito一起编写一些测试用例(包括对Controller的测试和对Repository的测试),感受下Spock的使用。

你可能感兴趣的:(使用Spock框架进行单元测试)