正式定义:
伪对象是通用术语,可以描述一个存根或者模拟对象(手工或非手工编写的),因为存根和模拟对象看上去都很像真实对象。一个伪对象究竟是存根还是模拟对象取决于它在当前测试中的使用方式:如果这个伪对象用来检验一个交互(需要对其进行断言),它就是模拟对象,否则就是存根。
引用自《单元测试的艺术 第2版》p70。
个人理解:
伪对象(FAKE)就是后两者的统称,模拟对象(mock)是一种功能更强大的存根(stub),模拟对象会记录交互的状态,不记录交互状态的就是存根。
解析:
单元测试中,我们经常会要调用到系统文件、系统时间、数据库、web服务等等我们无法控制的外部依赖,此时我们就需要制造伪对象(fake),来模拟这个外部依赖。如我们使用伪对象只是为了获取一个伪造的返回值,那么存根(stub)足以满足要求。如果我们不止需要获取伪造的返回值,我们在断言测试结果时,还需要判断伪对象的某个方法调用了几次、什么时候调用的,单纯的stub是不会记录这些状态的,我们需要用到功能更强大的模拟对象(mock)。
扩展阅读:
Spring rest Docs,自动化api文档生成工具,可以解放双手,让我们无需再手写接口文档(通常都是直接手写markdown)。相比 Swagger 那一大坨对代码高度入侵的注解, SRD是一种 测试驱动 的自动化文档生成工具。当然使用它的前提就是要会写单元测试。
-
一个单元测试只应该测试一件事,这是作者推荐的。如果一个测试中有多个模拟对象,说明你想要对多个结果进行断言,即你在测试多件事情。这样的测试过于复杂和脆弱。一般来说,一个测试只应关注一个模拟对象,一旦确定了模拟对象,其他的伪对象都应该用存根替代。
-
一个隔离框架是一套可编程的API,使用这套API创建的伪对象相比手工编写要容易得多,快得多,而且简洁的多。
-
对于同一个方法进进行多个入参和结果的测试,使用参数化测试是推荐的做法,可以大大减少冗余代码。
-
一个单元测试分三步:
- 准备数据
- 执行测试方法
- 断言测试结果