powermock模拟对象_使用PowerMock测试对象的内部状态

powermock模拟对象

大多数单元测试都集中于测试对象的行为以证明其有效。 这可以通过编写一个JUnit测试来实现,该测试调用对象的公共方法,然后测试这些调用的返回值是否与先前定义的一组期望值匹配。 这是一种非常常见且成功的技术。 但是,不应忘记对象也显示状态。 由于它是隐藏的,因此经常被忽略。

我于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模拟对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mono for android,Xamarin点击事件的多种写法

&#xff08;一&#xff09;原本java的写法&#xff08;相信很多是学过java的&#xff09;&#xff1a; 需要实现接口View.IOnClickListener&#xff0c;最好也继承类&#xff1a;Activity&#xff0c;因为View.IOnClickListener接口又继承了IJavaObject, IDisposable接口&…

51个赚钱的好方法

有很多方法赚钱。你可以在家工作&#xff0c;你可以做各种自由职业者&#xff0c;你可以在博客&#xff0c;也可以只保存。时间紧迫&#xff0c;我不知道任何人谁不喜欢做一些额外的现金。所以&#xff0c;我得给你51如何赚钱最好的方法的列表。 1.作为自由职业者的工作 工作作…

一句话木马绕过linux安全模式,一句话木马(webshell)是如何执行命令的

在很多的渗透过程中&#xff0c;渗透人员会上传一句话木马(简称webshell)到目前web服务目录继而提权获取系统权限&#xff0c;不论asp、php、jsp、aspx都是如此&#xff0c;那么一句话木马到底是如何执行的呢&#xff0c;下面我们就对webshell进行一个简单的分析。首先我们先看…

如何从finally块访问方法的结果值

尽管JVM是基于堆栈的计算机 &#xff0c;但Java语言实际上并没有为您提供任何访问该堆栈的方法。 即使有时&#xff0c;在极少数情况下&#xff0c;它也会非常有用。 一个例子 方法结果值放在堆栈中。 如果查看以下示例&#xff1a; public int method() {if (something)retu…

第六章 Qt布局管理器Layout

第六章 Qt布局管理器Layout 大家有没有发现一个现象&#xff0c;我们放置一个组件&#xff0c;给组件最原始的定位是给出这个控件的坐标和宽高值&#xff0c;这样Qt就知道这个组件的位置。当用户改变窗口的大小&#xff0c;组件还静静地呆在原来的位置&#xff0c;这有时候显然…

kafka集群状态Linux,Kafka集群配置

本文只要讲述Kafka集群的配置事项&#xff0c;包括zookeeper集群的配置。本文讲述的前提是kafka和zookeeper在单机情况下已正确安装和配置。如有疑问&#xff0c;可以参考《Linux(CentOS)中常用软件安装&#xff0c;使用及异常——Zookeeper, Kafka》。假设集群中有三台机器, i…

【APICloud系列|36】小米应用商店可以检测同个应用不同版本信息

在小米应用商店上架的信息 在其他应用商店上架的信息&#xff0c;比如应用宝 小米发过来的友好提示邮件&#xff1a;

VLAN的Hybrid和Trunk端口有何区别

有网友问这样一个问题&#xff1a; vlan 1 vlan 2 vlan 3 vlan 4 vlan 5 interface Ethernet0/1 port link-type hybrid port hybrid vlan 1 to 4 untagged port hybrid pvid vlan 2 interface Ethernet0/2 port link-type hybrid port hybrid vlan 3 to 5 untagged port hybri…

【APICloud系列|35】小米应用商店版本更新

1.在小米应用商店后天重新上传一个更新加固已经签名的安装包。 链接地址&#xff1a;https://dev.mi.com 2.完善资料&#xff0c;只需要填写更新日志简单说明更新的缘由&#xff0c;再次选择相应的语言即可。原来的内容还是存在的。 3.提交审核就行。

Linux光盘检测,qpxtool

软件简介各位使用Linux系统的刻录发烧友有福了。不用再为了检测光碟品质而切换到Windows系统了。因为在Linux系统里也有支持光碟品质检测的软件&#xff01;它的名字是QPxTool。虽说05年底QPxTool就诞生了&#xff0c;但最近才被以rpm包的形式提供给Fedora用户。首先看下它的界…

eclipse中tomcat能正常启动,在浏览器中不能打开问题

问题原因&#xff1a;没有在eclipse中tomcat的server location设置到tomcat的安装目录。 解决办法&#xff1a;1、选择server点击右键&#xff0c;选择Open选项&#xff0c;然后在server location栏设置tomcat的安装目录。 2、重新启动tomcat server。 3、在浏览器中输入&#…

存根类 测试代码 java_为旧版代码创建存根-测试技术6

存根类 测试代码 java任何阅读此博客的人都可能已经意识到&#xff0c;目前我正在开发一个项目&#xff0c;其中包含大量的旧代码&#xff0c;这些旧代码庞大&#xff0c;扩展且编写时从未进行过任何测试。 在使用此遗留代码时&#xff0c;有一个行为非常差的类非常普遍&#…

百度开发平台提交应用后进行官方认证审核失败?

昨晚收到一封来自百度的邮件 这里需要登录工业和信息化部查询后的ICP备案后的详细页面截图。&#xff08;其实也可以在备案的平台查询相关信息&#xff0c;我的是在阿里云备案的&#xff0c;所以直接去阿里云比较方便快捷&#xff09; 然后直接上传营业执照副本、ICP备案截图、…

linux字体如何删除不了,如何彻底替换Ubuntu下Chrome字体(清除楷体字)

刚刚升级到了Ubuntu 11.04,chrome也跟进到了11.0.696.57&#xff0c;让人纠结的依旧是Chrome内的字体&#xff0c;在首选项-->高级选项-->自定义字体并不能解决所有问题&#xff0c;还是有些网站看上去是令人纠结的楷体。在你的用户文件夹下(比如用户名为libai)选择显示所…

使用默认方法进行接口演化–第二部分:接口

引入了默认方法以启用接口演进。 如果向后兼容是不可替代的&#xff0c;则仅限于向接口添加新方法&#xff08;这是它们在JDK中的唯一用法&#xff09;。 但是&#xff0c;如果希望客户端更新其代码&#xff0c;则可以使用默认方法逐步演化接口而不会引起编译错误&#xff0c;从…

【APICloud系列|37】百度开放平台应用+,提升用户下载量操作步骤

进入百度应用开放平台后台&#xff0c;按图中步骤点击。 接入步骤 这个首先要准备和应用名称一致的百家号 链接地址&#xff1a; 进入官方号平台&#xff1a;http://gfh.baidu.com/ 填写官方的ID以及联系人的手机号即可&#xff0c;最后点击提交。

linux 命令 抛后台,Linux 后台执行命令

场景python 代码&#xff0c;打印1~3000&#xff0c;每秒打印一次## file_name: test.pyimport timei 0while 1:time.sleep(1)i i 1print(i)if i > 3000:break问题&#xff1a;直接在终端执行&#xff1a;python test.py, 需要在这个终端一直等&#xff0c;没法干别的事了…

【JSP】JSP与oracle数据库交互案例

************************************************************************ ****原文&#xff1a;blog.csdn.net/clark_xu 徐长亮的专栏 ************************************************************************ 本案例为咖啡销售情况录入查询系统 一、数据输入系统&…

【APICloud系列|34】上架华为应用市场缺少免责函?

针对华为应用市场&#xff0c;不管提交的是什么类型的应用&#xff0c;都应该提交免责函&#xff0c; 需要提前下载模板进行盖章后&#xff0c;转成图片上传。 免责函模板如下&#xff1a; 被拒绝的信息如下&#xff1a; 再次将免责函提交上去就没啥问题啦&#xff0c;因为其…

Property Animator 属性动画概述与示例

Property Animation 属性动画 属性动画是一个强大的框架&#xff0c;它几乎可以让你的所有东西做动画&#xff0c;你可以随着时间的推移通过更改他们的属性来定义动画&#xff0c;无论它是否绘制在屏幕上&#xff0c;一个属性动画是在指定的时间内去改变属性&#xff08;一个对…