使用PowerMock测试对象的内部状态
我于1995年夏季首次阅读Grady Booch的1994年的《 面向对象的分析和设计 》一书,它通过以下方式定义了对象的状态:
对象的状态包含对象的所有(通常是静态)属性以及这些属性中每个属性的当前(通常是动态)值。
他使用自动售货机示例定义了静态和动态状态之间的差异。 静态状态是通过机器始终准备好取钱的方式表现出来的,而动态状态是在任何给定实例中获得多少钱的状态。
我怀疑在这一点上,您会正确地辩称,显式行为测试确实会测试对象的状态,这是因为给定的方法调用返回了正确的结果,并且为了获得正确的结果,对象的状态也必须是是的...我会同意的。 但是,在极少数情况下,经典行为测试不适用。 当公共方法调用没有输出并且对对象不执行任何操作(更改其状态)时,会发生这种情况。 一个示例是返回void的方法或构造函数。 例如,给定一个具有以下签名的方法:
public void init();
…您如何确保已完成工作? 事实证明,有几种方法可以用来实现这一目标……
- 在您的类中添加许多getter方法。 这并不是一个特别好的主意,因为您只是在松开后门的封装。
- 放松封装:将私有实例变量打包为私有。 一个非常有争议的事情。 您可能会务实地认为,经过良好测试,正确和可靠的代码可能比具有高度的封装更好,但是我在这里不太确定。 这可能是一个短期修复,但将来可能会导致各种问题,因此应该有一种编写经过良好测试,正确和可靠的代码的方式,其中不包括破坏对象的封装
- 编写一些使用反射来访问对象内部状态的代码。 这是迄今为止最好的主意。 不利的一面是,这需要付出相当大的努力,并且需要一定数量的编程能力。
- 使用PowerMock的Whitebox测试课程为您完成艰苦的工作。
以下完全人为设计的方案演示了PowerMock的Whitebox类的用法。 它需要一个非常简单的AnchorTag <a>类,该类将在测试输入URL字符串有效之后构建一个锚标记。
public class AnchorTag {private static final Logger logger = LoggerFactory.getLogger(AnchorTag.class);/** Use the regex to figure out if the argument is a URL */private final Pattern pattern = Pattern.compile("^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$");/*** A public method that uses the private method*/public String getTag(String url, String description) {validate(url, description);String anchor = createNewTag(url, description);logger.info("This is the new tag: " + anchor);return "The tag is okay";}/*** A private method that's used internally, but is complex enough to require testing in its own right*/private void validate(String url, String description) {Matcher m = pattern.matcher(url);if (!m.matches()) {throw new IllegalArgumentException();}}private String createNewTag(String url, String description) {return "<a href=\"" + url + "\">" + description + "</a>";}
}
URL验证测试是使用正则表达式和Java Pattern对象完成的。 使用Whitebox类将确保正确配置模式对象,并且我们的AnchorTag处于正确的状态。 下面的JUnit测试证明了这一点:
/*** Works for private instance vars. Does not work for static vars.*/@Testpublic void accessPrivateInstanceVarTest() throws Exception {Pattern result = Whitebox.<pattern> getInternalState(instance, "pattern");logger.info("Broke encapsulation to get hold of state: " + result.pattern());assertEquals("^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$", result.pattern());}
该测试的关键是:
Pattern result = Whitebox.<pattern> getInternalState(instance, "pattern");
…使用反射返回Pattern对象的私有实例变量。 一旦可以访问该对象,我们只需调用它即可询问它是否已正确初始化:
assertEquals("^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$", result.pattern());
总而言之,我建议仅在无法使用简单直接的经典JUnit测试进行行为测试时,才应使用PowerMock显式测试对象的内部状态。 话虽如此,它是工具箱中的另一个工具,可以帮助您编写更好的代码。
参考:来自JCG合作伙伴的 PowerMock测试对象的内部状态 调试队长博客上的 Roger。
- JUnit 4.9(测试版3)中的规则
- Servlet 3.0异步处理可将服务器吞吐量提高十倍
- 用Scala测试
- Java工具:源代码优化和分析
- Java教程和Android教程列表
翻译自: https://www.javacodegeeks.com/2011/10/testing-objects-internal-state-with.html
使用PowerMock测试对象的内部状态相关推荐
- powermock模拟对象_使用PowerMock测试对象的内部状态
powermock模拟对象 大多数单元测试都集中于测试对象的行为以证明其有效. 这可以通过编写一个JUnit测试来实现,该测试调用对象的公共方法,然后测试这些调用的返回值是否与先前定义的一组期望值匹配 ...
- 【设计模式】享元模式 简介 ( 定义 | 对象池 | 内部状态 | 外部状态 | 适用场景 | 相关角色 )
文章目录 I . 享元模式 简介 II . 享元模式 内部状态 和 外部状态 III . 享元模式 适用场景 IV . 享元模式 优缺点 V . 享元模式 相关模式 VI . 享元模式 相关角色 I ...
- 处理对象的多种状态及其相互转换——状态模式
本文转载自 :http://blog.csdn.net/lovelion/article/details/8522982 "人有悲欢离合,月有阴晴圆缺",包括人在内,很多事物都具有 ...
- 软件测试基础 按照测试对象划分 界面测试(UI测试.响应式页面 可靠性测试 容错性测试 文档测试 平台测试 易用性测试等
软件测试进阶 1.APP 的测试 2. 按照测试对象划分 2.1界面测试(UI测试) 3.响应式页面 4.可靠性测试 5.容错性测试 6.文档测试 7.平台测试: 7.1 PC: 7.2.手机端: 8 ...
- NVME CLI -- nvme 命令查看NVME设备内部状态
文章目录 NVME 和 AHCI 性能比较 NVME-CLI nvme工具使用 1. 安装 2. 命令综述 3. 基本命令演示 4. NVME 固件设备升级 近期在做一些rocksdb on 新硬件的 ...
- Hibernate持久化对象三种状态
持久化类类三种状态介绍 瞬时态:也叫做临时态或自由态,它一般指我们new出来的对象,它不存在OID,与hibernate session无关联,在数据库中也无记录.它使用完成后,会被jvm直接回收掉, ...
- powermock模拟对象_使用PowerMock模拟构造函数
powermock模拟对象 在我看来,依赖注入的主要好处之一是可以将模拟和/或存根对象注入代码中,以提高可测试性,增加测试覆盖率并编写更好,更有意义的测试. 但是,有时候您会遇到一些不使用依赖注入的传 ...
- AGS 对象池和状态概要
AGS是ArcGIS Server的简称,AGS开发首先要理解对象池和状态(object pooling and gis server state),ags帮助文档对此有很详细的描述,想在短时间内看完 ...
- 对象的当前状态使该操作无效 说明: 执行当前 Web 请求期间,出现未处理的异常。...
这个异常在页面数据量小的时候并不会触发,只在页面数据量大的情况下才会出现, 异常信息如下: 对象的当前状态使该操作无效. 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以 ...
最新文章
- HDU - 5788 Level Up(主席树+dfs序+树状数组)
- 再见Spring Security!推荐一款功能强大的权限认证框架,用起来够优雅!
- java 自动化测试报告_Java自动化测试框架-10 - TestNG之测试结果篇
- python里order_volume_Python 基础知识:Method Resolution Order (MRO) 和 super
- jquery显示隐藏切换_jQuery显示,隐藏,切换
- [20170925]什么是FQDN(关于hostname).txt
- 简单的Latex模板
- 一二线城市都有哪些互联网公司是大家都想去的?
- 一些常用软件的网络端口协议分类介绍
- 软考-软件工程师常用公式及知识点
- 设计在链式存储结构上交换二叉树中所有结点左右子树的算法
- matlab函数power,Matlab中Powergui介绍.pdf
- tippy.js悬浮提示工具插件
- Windows10黑体字体
- RecyclerView滑动置顶点击置顶的实现
- 数据挖掘ID3算法详解
- 使用matplotlib绘制折线图(绘制一天当中的气温变化)
- win10提示bitlocker加密的硬盘需要格式化
- 全球与中国5G用聚酰亚胺薄膜市场深度研究分析报告
- 【做题笔记】P2327 [SCOI2005]扫雷
热门文章
- mybatis多表新增如何获取主键ID
- 如何实现下拉框的绑定
- spring注入私有字段_Spring字段依赖注入示例
- 结果集 tostring_关于避免对toString()结果进行解析或基于逻辑的美德
- python kotlin_Java和Python中类似Kotlin的生成器,续:附加参数
- javaone_JavaOne 2015 –第二十版十大收获
- JavaFX的科幻用户界面第1部分
- 借助Fargate和EKS,AWS甚至可以实现Cloud-ier和Kuberneties-ier
- jsf tree组件_JSF:在传统组件和时尚性能杀手之间进行选择
- threadlocals_如何使用ThreadLocals射击自己