- 单元测试
- 可测试
- 接口
- 面向接口
单元测试
一个代码质量和工程质量有保证的项目一定有比较合理的单元测试覆盖率,没有单元测试的项目一定是不合格的或者不重要的,单元测试应该是所有项目都必须有的代码,每一个单元测试都表示一个可能发生的情况,单元测试就是业务逻辑。
可测试
写代码并不是一件多困难的事情,不过想要在项目中写出可以测试的代码并不容易,而优雅的代码一定是可以测试的。
如果想要想清楚什么样的才是可测试的,我们首先要知道测试是什么?测试就是控制变量,在我们隔离了待测试方法中一些依赖之后,当函数的入参确定时,就应该得到期望的返回值。
如何控制待测试方法中依赖的模块是写单元测试时至关重要的,控制依赖也就是对目标函数的依赖进行 Mock 消灭不确定性,为了减少每一个单元测试的复杂度,我们需要:
- 尽可能减少目标方法的依赖,让目标方法只依赖必要的模块;
- 依赖的模块也应该非常容易地进行 Mock;
单元测试的执行不应该依赖于任何的外部模块,无论是调用外部的 HTTP 请求还是数据库中的数据,我们都应该想尽办法模拟可能出现的情况,因为单元测试不是集成测试的,它的运行不应该依赖除项目代码外的其他任何系统。
接口
在 Go 语言中如果我们完全不使用接口,是写不出易于测试的代码的,作为静态语言的 Go,只有我们使用接口才能脱离依赖具体实现的窘境,接口的使用能够为我们带来更清晰的抽象,帮助我们思考如何对代码进行设计,也能让我们更方便地对依赖进行 Mock。
面向接口
软件设计中经常被提到的一句话 — 『依赖接口,不要依赖实现』
面向接口编程是一个老生常谈的话题,接口的作用其实就是为不同层级的模块提供了一个定义好的中间层,上游不再需要依赖下游的具体实现,充分地对上下游进行了解耦。
如果一个略有规模的项目中没有出现任何 type ... interface 的定义,那么可以推测出这在很大的概率上是一个工程质量堪忧并且没有多少单元测试覆盖的项目,我们确实需要认真考虑一下如何使用接口对项目进行重构。