- 浏览: 1051376 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (1355)
- test (75)
- 红茶和绿茶 (1)
- Jave SE (206)
- Oracle (19)
- English (177)
- Log4j (5)
- RIA(Rich Internet Applications) (9)
- Ext Js (6)
- Android (14)
- Logo (0)
- 文字采撷 (287)
- 使用技巧 (92)
- Project Management (22)
- Hibernate (12)
- Struts (5)
- 规则引擎 (1)
- Html & Javasctipt (56)
- Spring MVC (10)
- Maven (17)
- Java Test (17)
- Linux (16)
- Tools (1)
- CV (0)
- Middleware (2)
- HTML5 (2)
- Algorithms (4)
- Web Service (15)
- 留学 (15)
- LADP (5)
- PXCOA (0)
- SysLog (6)
- SSO (3)
- Spring Security (4)
- Spring Batch (1)
- Jmail (1)
- Bible (4)
- Java Thread (5)
- Architect (6)
- github (2)
- Java Swing (12)
- NoSQL (7)
- UML (2)
- 敏捷(Agile) (7)
- Hudson+Maven+SVN (15)
- cloud computing (2)
- Bahasa Indonesia (1)
- jBPM (6)
- 民俗知识 (3)
- Consulting (1)
- Mysql (5)
- SAP (1)
- 微信公众平台接口开发 (3)
- 做生意 (1)
- 西餐 (1)
- Banking (1)
- Flex (0)
- 黄金投资 (1)
- Apache Tomcat 集群 (3)
- Hadoop (7)
- 需求分析 (1)
- 银行知识 (3)
- 产品管理 (2)
- 钢琴Music (3)
- 设计 (3)
- Marketing (2)
- US Life (3)
- 算法 (14)
- BigData (4)
- test红茶和绿茶Jave SEOracleEnglishLog4jRIA(Rich Internet Applications)Ext JsAndroidLogo文字采撷 (0)
- Design Pattern (5)
- NodeJS&AngularJS (9)
- Python (1)
- Spring boot (0)
- ACM (3)
最新评论
-
心往圣城:
微时代-最专业的微信第三方平台。LBS定位导航,微网站,自定义 ...
微信公众平台 /微信公众平台怎么用 -
zhaojiafan:
return ReverseStr1(str.substrin ...
逆转字符串 Write a String Reverser (and use Recursion!) -
zhaojiafan:
public class StringUtils {
p ...
逆转字符串 Write a String Reverser (and use Recursion!)
JMock是帮助创建mock对象的工具,它基于Java开发,在Java测试与开发环境中有不可比拟的优势,更重要的是,它大大简化了虚拟对象的使用。本文中,通过一个简单的测试用例来说明JMock如何帮助我们实现这种孤立测试。
我们在测试某类时,由于它要与其他类发生联系,因此往往在测试此类的代码中也将与之联系的类也一起测试了。这种测试,将使被测试的类直接依赖于其他类,一旦其他类发生改变,被测试类也随之被迫改变。更重要的是,这些其他类可能尚未经过测试,因此必须先测试这些类,才能测试被测试类。这种情况下,测试驱动开发成为空谈。而如果其他类中也引用了被测试类,我们到底先测试哪一个类?因此,在测试中,如果我们能将被测试类孤立起来,使其完全不依赖于其他类的具体实现,这样,我们就能做到测试先行,先测试哪个类,就先实现哪个类,而不管与之联系的类是否已经实现。
版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接
作者:Sarkuya(作者的blog:http://blog.matrix.org.cn/page/Sarkuya)
原文:http://blog.matrix.org.cn/page/Sarkuya?entry=%E4%BD%BF%E7%94%A8jmock%E6%9D%A5%E5%AE%9E%E7%8E%B0%E5%AD%A4%E7%AB%8B%E6%B5%8B%E8%AF%95
关键字:JMock;Testing
虚拟对象(mock object)就是为此需要而诞生的。它通过JDK中的反射机制,在运行时动态地创建虚拟对象。在测试代码中,我们可以验证这些虚拟对象是否被正确地调用了,也可以在明确的情况下,让其返回特定的假想值。而一旦有了这些虚拟对象提供的服务,被测试类就可以将虚拟对象作为其他与之联系的真实对象的替身,从而轻松地搭建起一个很完美的测试环境。
JMock是帮助创建mock对象的工具,它基于Java开发,在Java测试与开发环境中有不可比拟的优势,更重要的是,它大大简化了虚拟对象的使用。
本文中,通过一个简单的测试用例来说明JMock如何帮助我们实现这种孤立测试。有三个主要的类,User,UserDAO,及UserService。本文中,我们只需测试UserService,准备虚拟UserDAO。对于User,由于本身仅是一个过于简单的POJO,可以不用测试。但如果你是一个完美主义者,也可以使用JMock的虚拟它。在这领域,JMock几乎无所不能。:)
User是一个POJO,用以在视图中传输数据及映射数据库。其代码如下:
package com.sarkuya.model; public class User { private String name; public User() { } public User(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
UserDAO负责与数据库打交道,通过数据库保存、获取User的信息。尽管我们可以不用知道JMock如何通过JDK的反射机制来实现孤立测试,但至少应知道,JDK的反射机制要求这些在运行时创建的动态类必须定义接口。在使用JMock的环境中,由于我们要虚拟UserDAO,意味着UserDAO必须定义接口。代码如下:
package com.sarkuya.dao; import com.sarkuya.model.User; public interface UserDAO { public void saveUser(User user); public User getUser(Long id); }
UserService存有UserDAO的引用,通过其对外提供应用级的服务。相应地,我们先定义了其接口(尽管在本文中,作为被测试类,UserService不需要有接口,但如果以后此类需要被虚拟,也应该带有接口,基于此原因,我们也为其定义了接口)。
package com.sarkuya.service; import com.sarkuya.dao.UserDAO; import com.sarkuya.model.User; public interface UserService { public void setUserDAO(UserDAO userDAO); public void saveUser(User user); public User getUser(Long id); }
可以看到,除了setUserDAO()外,其另外的方法与UserDAO一样。这是设计模式中门面模式的典型应用,应用只通过UserService提供服务,而UserService在内部通过调用UserDAO来实现相应的功能。
根据测试先行的原则,你应该先写测试,再编写实现。这里先编写实现的原因,主要是使读者更加清楚我们接着要测试什么。由于本文是着重介绍JMock的使用,加上UserServiceImpl比较简单,因此先列出其代码如下:
package com.sarkuya.service.impl; import com.sarkuya.dao.UserDAO; import com.sarkuya.model.User; import com.sarkuya.service.UserService; public class UserServiceImpl implements UserService { private UserDAO userDAO; public UserServiceImpl() { } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } public User getUser(Long id) { return userDAO.getUser(id); } public void saveUser(User user) { userDAO.saveUser(user); } }
下面是UserService的测试代码:
package com.sarkuya.service; import com.sarkuya.dao.UserDAO; import com.sarkuya.model.User; import com.sarkuya.service.impl.UserServiceImpl; import junit.framework.*; import org.jmock.Mock; import org.jmock.MockObjectTestCase; public class UserServiceTest extends MockObjectTestCase { private UserService userService = new UserServiceImpl(); private Mock userDAO = null; public UserServiceTest(String testName) { super(testName); } protected void setUp() throws Exception { userDAO = new Mock(UserDAO.class); userService.setUserDAO((UserDAO)userDAO.proxy()); } protected void tearDown() throws Exception { } public static Test suite() { TestSuite suite = new TestSuite(UserServiceTest.class); return suite; } public void testGetUser() { User fakeUser = new User("John"); userDAO.expects(once()).method("getUser").with(eq(1L)).will(returnValue(fakeUser)); User user = userService.getUser(1L); assertNotNull(user); assertEquals("John", user.getName()); } public void testSaveUser() { User fakeUser = new User("John"); userDAO.expects(once()).method("getUser").with(eq(1L)).will(returnValue(fakeUser)); User user = userService.getUser(1L); assertEquals("John", user.getName()); userDAO.expects(once()).method("saveUser").with(same(fakeUser)); user.setName("Mike"); userService.saveUser(user); userDAO.expects(once()).method("getUser").with(eq(1L)).will(returnValue(user)); User modifiedUser = userService.getUser(1L); assertEquals("Mike", user.getName()); } }
此段代码有几点应注意:
1、此测试类继承了JMock的MockObjectTestCase
2、private Mock userDAO = null;说明userDao是一个准备虚拟的对象
3、在setup()中,将userDAO.class传入Mock()后,再通过proxy()方法返回一个UserDAO的代理类实例(即虚拟对象实例),并赋值于userService
4、在testGetUser()方法中,如果我们先将第一行及第二行代码屏蔽掉,可以看出,这是一个真实环境下的测试代码。先获取一个User,然后确认其非空值,再确认其姓名为“John”。此时,在真实环境下,这段代码要测试成功的前提必须是UserDAO已经连接到了数据库,然后返回一个User后传给UserService。
但问题是,到目前为止,且不说UserDAO还未经历连接数据库这一系列繁琐而痛苦的过程,我们甚至还未实现UserDAO的接口!那么,为何加上第一行及第二行代码后就可以了呢?这正是JMock的威力所在。先实例化一个测试用的fakeUser,然后通过一系列的指令,在第二行代码中告诉JMock应该如何“做假”。尽管这句代码很长,我们可作如下理解:
1) userDAO.expects(once()):我们期望userDAO的某方法被执行一次,如果此方法未被执行,或者执行了二次以上,测试就不会通过
2) method("getUser"):这个期望被执行一次的方法名为userDAO.getUser()
3) with(eq(1L)):执行getUser()方法时,确认其传入的参数值为“1L”
4) will(returnValue(fakeUser)):上述条件均满足后,返回一个虚假的对象,即我们前面实例化的fakeUser
总体来说,当设定好第二行语句后,JMock就在后台监控着,确保userDAO.getUser()必须,且只被执行一次,且参数“1L”已经正确地传给了此方法,一旦这些条件被满足,就返回fakeUser。
而在第三行,User user = userService.getUser(1L)将触发所有这些条件,作为奖励,它接受了奖品fakeUser并赋值于user对象。而下面第四行及第五行均对此user对象进行测试,不通过才怪。
5) testSaveUser()方法中的原理类似。其思路是,将id为“1”的user从数据库中取出,将其名改为“Mike”,再存回数据库,然后再从数据库中取出此user,确保其名字已被改变。
第五行userDAO.expects(once()).method("saveUser").with(same(fakeUser))比较特殊。首先,with(same(fakeUser))说明,传入参数必须是fakeUser此实例,尽管我们在下面的语句中通过user.setName("Mike"),但只是改变了其name的属性,而fakeUser的实例引用并未发生改变,因此可以满足条件。其次,其后没有.will(returnValue(fakeUser)),因为userDAO.saveUser()不需要返回任何对象或基本数据类型。
另外,当再次执行userDAO.expects()时,JMock将重设其监控条件。我们也可以通过userDAO.reset()来显式是清除监控条件。
通过以上实例代码及其说明,我们看出,用好JMock的关键是先设置监控条件,再写相应的测试语句。一旦设好监控条件后,在某段代码块执行完毕时,如果监控条件未得到满足,或是没有通过expects()再次重设条件,或通过reset()来显式是清除监控条件,测试将无法通过。
以上介绍了JMock的基本使用方法。而这种基本用法,占了全面掌握JMock所需学习的知识70%以上。关于JMock的更多细节,感兴趣的读者可以访问JMock的网站进一步学习。
发表评论
-
JUnit4概述 (非常好的文章for java unit test)
2012-10-23 15:31 1038JUnit4是JUnit框架有史以来的最大改进,其主要目标 ... -
Weblogic remote debugger java
2012-09-06 15:15 732window version 1, add b ... -
Base code of using Junit and Jmock write unit test case
2012-09-06 15:09 879mock class and mock interface ... -
jMock Cookbook 中文版一
2012-02-07 10:50 1249入门 定义期望 模拟 ... -
[1.18开始更新了北风网&风中叶录制的JUNIT详解-Spring.MVC3.0.WEB框架系列---北风网讲师深入讲解Java编程陷阱及面试指导系列课程(共
2012-02-06 00:05 2[1.18开始更新了北风网&风中叶录制的JUNIT详解 ... -
(来自IBM) JUnit4 与 JMock 之双剑合璧
2012-02-03 15:29 1215引言 单元测试可以保证代码的质量,最大程度降低修复系统 bu ... -
maven+jmock
2012-02-03 13:50 962Maven + jmock + dependency +rep ... -
Junit使用指南及作业规范.pdf (Open-Open)
2012-02-05 23:09 849Junit使用指南及作业规范.pdf http:// ... -
junit示例
2012-02-05 23:10 909junit示例 1.TestCase最 ... -
(来自IBM)单元测试利器 JUnit 4
2012-02-03 15:27 822引言 毋庸置疑,程序 ... -
JUnit三分钟教程 ---- 快速起步
2012-02-05 23:09 850JUnit三分钟教程 ---- 快速起步 JUnit是个好东西 ... -
Junit
2012-02-02 11:16 939第一,junit使用很方便 ... -
Jmock Jar Package
2012-02-02 14:02 815Jmock -
Growing Object-Oriented Software Guided by Tests
2012-02-02 14:02 1008About the Book <script>& ... -
jmock2:getting started with junit4
2012-02-01 17:53 1030最近想玩玩JMock。对着官方文档,想开始写个test c ... -
使用MOCK对象进行单元测试
2012-02-01 17:34 1093测试之道 1.出了什么问题? 单元测试的 ... -
jmock
2012-02-01 15:19 1483一、介绍 JMock是一个使用模拟对象机制测试Java ...
相关推荐
2000-2021年中国科技统计年鉴(分省年度)面板数据集-最新更新.zip
PPT保护工具PDFeditor专业版-精心整理.zip
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
考研英语真题及详解-精心整理.zip
Jupyter-Notebook
全国电子地图行政区划道路水系数据-最新shp.zip
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
地级市进出口贸易及外资利用数据(297城)-最新.zip
HengCe-18900-2024-2030中国皮革制品市场现状研究分析与发展前景预测报告-样本.docx
猪脚饭超好吃 java制作的小游戏,作为巩固java知识之用.zip
【基于Python的大麦网自动抢票工具的设计与实现】 随着互联网技术的发展,网络购票已经成为人们生活中不可或缺的一部分。尤其是在文化娱乐领域,如音乐会、演唱会、戏剧等活动中,热门演出的门票往往在开售后瞬间就被抢购一空。为了解决这个问题,本论文探讨了一种基于Python的自动抢票工具的设计与实现,旨在提高购票的成功率,减轻用户手动抢票的压力。 Python作为一种高级编程语言,因其简洁明了的语法和丰富的第三方库,成为了开发自动化工具的理想选择。Python的特性使得开发过程高效且易于维护。本论文深入介绍了Python语言的基础知识,包括数据类型、控制结构、函数以及模块化编程思想,这些都是构建抢票工具的基础。 自动化工具在现代社会中广泛应用,尤其在网络爬虫、自动化测试等领域。在抢票工具的设计中,主要利用了自动化工具的模拟用户行为、数据解析和定时任务等功能。本论文详细阐述了如何使用Python中的Selenium库来模拟浏览器操作,通过识别网页元素、触发事件,实现对大麦网购票流程的自动化控制。同时,还讨论了BeautifulSoup和requests库在抓取和解析网页数据中的应用。 大麦网作为国内知名的票务平台,其网站结构和购票流程对于抢票工具的实现至关重要。论文中介绍了大麦网的基本情况,包括其业务模式、用户界面特点以及购票流程,为工具的设计提供了实际背景。 在系统需求分析部分,功能需求主要集中在自动登录、监控余票、自动下单和异常处理等方面。抢票工具需要能够自动填充用户信息,实时监控目标演出的票务状态,并在有票时立即下单。此外,为了应对可能出现的网络延迟或服务器错误,工具还需要具备一定的错误恢复能力。性能需求则关注工具的响应速度和稳定性,要求在大量用户同时使用时仍能保持高效运行。 在系统设计阶段,论文详细描述了整体架构,包括前端用户界面、后端逻辑处理以及与大麦网交互的部分。在实现过程中,采用了多线程技术以提高并发性,确保在抢票关键环节的快速响应。此外,还引入了异常处理机制,以应对网络故障或程序错误。 测试与优化是确保抢票工具质量的关键步骤。论文中提到了不同场景下的测试策略,如压力测试、功能测试和性能测试,以验证工具的有效性和稳定性。同时,通过对抢票算法的不断优化,提高工具的成功率。 论文讨论了该工具可能带来的社会影响,包括对消费者体验的改善、对黄牛现象的抑制以及可能引发的公平性问题。此外,还提出了未来的研究方向,如增加多平台支持、优化抢票策略以及考虑云服务的集成,以进一步提升抢票工具的实用性。 本论文全面介绍了基于Python的大麦网自动抢票工具的设计与实现,从理论到实践,从需求分析到系统优化,为读者提供了一个完整的开发案例,对于学习Python编程、自动化工具设计以及理解网络购票市场的运作具有重要的参考价值。
校园驿站全天候辅助取货管理系统 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
1970年至2010年美国所有乳制品的供应和利用情况
java基础 java_leetcode题解之Possible Bipartition.java
该开源项目为阿里巴巴数据库事业部精心打造的druid连接池设计源码,包含4689个文件,涵盖4069个Java源文件、297个SQL脚本、102个文本文件以及其他多种文件类型。druid连接池以其独特的监控功能,旨在为数据库连接管理提供高效、可靠的解决方案。项目文件类型丰富,包括HTML、JavaScript、CSS和Shell脚本等,适用于多种开发需求。
Jupyter-Notebook
金融风险管理计算手册(CoVaR)最新版.zip
网上选课系统 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
Jupyter-Notebook
Jupyter-Notebook