引用
第一是事件录制的代码量相当大,而且干扰TestCase的可读性。比如函数返回一个Book,我就要手工设置这个Book所有测试相关的属性,如果返回的是Book List,那就更加.....如果分支很多,你还要不断重复录制....比如它如果有嵌套的函数调用,还要一个个录下去....看到眼花时,还很干扰你的测试校验代码。
做单元测试的时候,准备的测试数据应该是符合条件最简化的形式,只准备最必须的最少最简单的数据形式。例如测试一个Book是否被load,你只需要放一个book.name就足够了,无需准备更多的数据。如果是Book List,你仅仅需要准备两个book对象足够了。这样算下来,其实测试数据的准备量并不大,至少我写的单元测试里面,我感觉这部分工作量实在不算什么,比起来真实环境跑起来的时候那些复杂的数据,真的是太简单的工作了。
不管你用不用mock对象,如果功能代码的分支流程很多的话,你必须要为每个分支单独写一个testXXX去测试它,否则你的单元测试就是不完备的,这和mock不mock没有任何关系。
至于说嵌套很深的调用,就一定说明你的设计有问题。对象调用应该遵循迪米特法则,只调用触手可及的对象。
引用
第二是代码重复的bad smell,比如ApplicationContext.xml定义好了的对象管理关系,Test里又手工设置了一次。
更重要是本来bookManager的sell方法,无论是接口和行为定义都只有一个地方,引入mockObject后,每一个录制mockObject 的地方,就多了一个对该函数接口和行为的定义,代码修改和重构时很麻烦(注意,这和unit test对重构的支持是两个不同的概念)
首先你一个bean会依赖很多其他bean吗(如果依赖过多bean,就要审视一下是否是设计的问题)?其次在一个testcase里面,你给一个bean set几个mock对象是很麻烦的事情吗?这叫做代码重复的bad smell?
你的功能代码里面,其他的bean调用了bookManager的sell方法算不算对该函数接口和行为的定义?你代码修改和重构的时候,难道你都不需要去关注别的功能代码对该函数的调用吗?
在强调针对接口编程的情况下,无论是功能代码对该接口的调用bookManager.sell(...)(接口实现类通过spring容器注入),还是Test代码对该接口的调用bookManager.sell(...)(接口实现类是Mock对象),有什么区别呢?
引用
因此,如果强制全程推行的话,代码量那是相当壮观,lighter,faster java的口号也白喊了,什么lighweight框架省下的代码还不够ut里填的。 1行代码,10行测试对于国内大部分资源少,时间紧的团队来说还是太奢侈了。
如果功能代码的分支流程比较多,你确实可能需要写非常长的测试代码去覆盖每个流程,上周末BEA SHUG,我请教过红工场Charles Huang,他告诉我,测试代码是功能代码的两三倍都是很正常的事情。不能因为测试代码量大就拒绝进行完备的单元测试编写。因为越是项目后期,有一个完备的单元测试集,你就对项目代码的信心越足。特别是项目代码树已经非常庞大的情况下,你需要对底层架构进行比较大的调整的时候,单元测试集是你成功的保证,当你完成底层架构的调整之后,看到几百个test全部green bar的时候,心情之爽是难以言表的。
写完备的test case,开始看起来似乎拖慢了速度,但是他确实可以保证软件开发整个过程以稳健的速度前进,而且控制的了风险。特别是对那些需求非常模糊和变动非常剧烈的项目,在整个开发过程中,不断调整底层框架是非常频繁的事情,当你的整个codebase变得比较大的时候,如果没有完备的单元测试,你是绝对没有信心去调整的,而不断妥协的结果就是codebase越来越腐烂,最后变得无法继续开发,推倒重来。其实我现在越来越感觉到,写单元测试是程序员对自己负责任的行为。如果你不想项目后期频繁加班,如果你不想面对一个无法下手的项目,如果你不想痛苦的维护一个很烂的codebase,如果你希望心情愉快,每天按时上下班的话,写完备的单元测试就是达成你快乐工作的前提。
另外写单元测试也会强迫你编写出来高质量的功能代码。因为低劣的功能代码是极难测试或者根本不可测试的。而只有始终保持高质量的功能代码,你才会对项目的周期和质量有信心,而对于每个有追求的程序员来说,面对一个高质量代码的项目,无论如何都是心情很愉快的事情。
虽然我不喜欢像一些人一样总是推荐别人读这本书,那本书什么的。不过你的这些疑问在without EJB第14章单元测试里面都有非常明确的分析和解答。另外也非常值得看一下Kent Beck的《TDD by example》,很多问题里面都有解答。
相关推荐
不错的文档,提供给科研人员
mock-server服务器端数据模拟,方便前端工程师独立于后端进行开发。支持跨域访问,支持post大文件(不会在硬盘上进行存储)。本程序根据个人的实际使用情况在操作的简便性和功能的丰富性之间做了适当的取舍,“返回...
MockObject类具有两个主要功能: * 它维护一个函数返回值的查找表:对于任何函数,对于特定函数,或者对于具有特定参数的特定函数*它维护了调用方法的列表以及使用的参数。 例子 有关如何工作的示例,请参阅示例子...
模拟请求 请求解析器安装 npm install mock-request2用法 var Request = require('mock-request2');var request = new Request({ uri: 'http://localhost:8080/path/to/some/resource', method: 'POST',});// ...
redis-mock-java 用纯Java编写的与内存Redis兼容的实现。 。地位安装专家< dependency> < groupId>org.rarefiedredis.redis</ groupId> < artifactId>redis-java</ artifactId> < version>0.0.5</ version></ ...
graphql-mock-object使您的UI可以根据需要轻松地请求数据。 完成原型制作后,您可以使用真实的解析器替换模拟并返回真实的数据。 安装 我建议保存到devDependencies ,因为原型production通常在development完成,而...
节点 auto_mock_server.js 或使用 npm 标准命令:npm start(在项目目录中)如何配置端口: 默认情况下,服务器在端口 8000 上运行,您可以将参数传递给应用程序以更改使用的端口: 节点 auto_mock_server.js 8001...
xiaoyaoji-mock-server 该工具旨在帮助您启动并使用xiaoyaoji模拟服务器。要求节点>=7.6.0. npm >=5.6.0入门在确认您的开发环境满足指定的,您可以按照以下步骤启动并运行项目: $ git clone $ cd xiaoyaoji-mock-...
vue3+vite+pinia+axios+mock+ElementPlus js 登录,动态路由,存储pinia,网络axios+mock
SimpleMock.jl:基本的模拟模块
generator-mock-server Installation First, install and generator-mock-server using (we assume you have pre-installed ). npm install -g yo npm install -g generator-mock-server Then generate your new ...
嘲笑 受 python 模拟功能启发的简单模拟
Real_Estate_Mock_Page:完整的模拟Django项目
akka-mock-scheduler:一个模拟的Akka调度程序,可简化测试与调度程序相关的代码
前端需要mock后端的服务进行测试,采用mock服务有以下一些好处: 前端不再依赖后端接口,可以先行测试,能使后期的联调效率更加高效。 方便一些边界case的模拟,降低沟通成本。mock测试可以更低成本的完成前端测试。...
webpack-mock-middleware 在webpack开发模式,该中间件配合devServer.before提供了一种快速本地mock数据的方案。 mock目录下为数据js,与接口地址相对应,如axios.get('/api/user') -> mock目录下api/user.js 用法 #...
上面列出的对“管理”端点的所有请求都必须包含标头X-Pact-Mock-Service: true以允许模拟服务知道该请求是管理请求还是来自实际使用者代码的请求。 由于Pact模拟服务可以用作独立的可执行文件并通过HTTP进行管理,...
npm install --save-dev mock-stdio 例子 var mockIo = require ( 'mock-stdio' ) ; var expect = require ( 'chai' ) . expect ; describe ( 'thing' , function ( ) { it ( 'writes to standard out' , function...
var mockStore = require('aws-mock-store'); 存储对象 mockStore.create(myObject, function(err, createdObjectId) { if (err) { console.log(err); } else { console.log("Randomly generated unique ...
knex-mock-tester:模拟测试使用knex的功能而无需建立任何连接或调用sql方言的功能