大部分程序员有两个特点:一不愿意写文档和注释,二不愿意写单测。单元测试是黑盒测试的基础,基本的准入测试,既能验证逻辑的准确性,又能给后续的接口重构提供基础。总之就是『单元测试很重要』,在敏捷迭代开发过程中,开发人员往往对单元测试不够重视,主要原因还是排期紧,比如我们团队初期对单测的要求是所有的 dao 层都要进行单测覆盖,到后来时间充裕才在 service 层进行单元测试的补充。controller 层的单元测试由于经常采用 mock 对象,很多人嫌繁琐就索性直接跟前端联调,不去管了。那为什么要写单元测试?单元测试能以更细的粒度,构造更多的业务场景,模拟更多的输入行为,在此过程中保证程序行为如程序员所想。单元测试可以驱动重构,通过重构进而优化代码本身,为什么这么说呢?因为单元测试对于被测试代码是有要求的,那什么是好的代码呢?援引一个我认识的架构师的观点,好的代码有以下特点:可读性。代码整洁有序;命名规范,见名知意(get/load, create/build), 在方法没有好到见名知意或者有特殊业务逻辑时,加必要注释。扩展性,易维护性。合理规划变和不变(核心业务逻辑不变);抽取模块、服务、方法;NO 复制粘贴效率。避免一个请求对远程服务/数据库重复请求可测性。避免大而全的方法,一个方法只做一件事(大方法抽取出多个可测小方法);相似的事情尽量合并成一个方法(比如 dao,sql 不要写死,尽量一个 sql 可以做多件事情)其中可测性是单元测试对代码的基本要求,所以当你发现代码不可测试了,是时候重构了,这也是一个代码重构时机的判断标准。
那么如何写好单元测试:单一职责,每个 case 测试一件事情,原子无歧义,失败无需 debug;case 按照业务场景拆分,注释保证覆盖全面,追加删除方便;测试的 case 间没有依赖;case 之间无冗余;case 干净。(数据库、磁盘、程序状态等)前后保持一致
最近负责一个复杂改动逻辑较多的迭代,对较多业务模块进行了重构,写了很多单元测试。所以顺便做个总结,单元测试是自己代码逻辑的检查员,是别人阅读你代码的入口,也是重构的保障

最近看 Eureka 的源码,看源码除了从任何一个函数作为入口着手外,有个很好的技巧就是从单元测试入手,本章最后来两张图来看下 Eureka 源码的单元测试,这种测试驱动的思想和做法值得我们学习。

JAVA单元测试总结 java单元测试的作用_单元测试

图1可以清晰看到 eureka server 初始化过程:初始化配置、启动服务、创建 eureka server 加载配置,通过该入口进去可以看到 eureka 初始化的所有细节。

JAVA单元测试总结 java单元测试的作用_业务逻辑_02

上图是服务的注册、发送心跳(renew 续约)以及失去心跳的入口,比直接找源码简单很多。

JAVA单元测试总结 java单元测试的作用_业务逻辑_03