使用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

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

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

相关文章

布局

1&#xff09;ul li 把ul宽度设置大一点&#xff0c;然后overflowhidden;&#xff08;最好不要嵌套使用&#xff0c;原因看清除浮动方法&#xff09;&#xff0c;然后外面必须有包裹的div壳&#xff0c;div壳的宽度就按设计稿来&#xff0c;这样就避免了需要给最后一个li设置m…

10个职场故事,让人不得不看

1、强盗师徒 有一次&#xff0c;一个老强盗带着徒弟去抢劫银行&#xff0c;被警方追捕。两人狂逃&#xff0c;差点儿连裤子都跑掉了。好不容易甩掉了警察&#xff0c;两人上气不接下气&#xff0c;瘫倒在地上。 良久&#xff0c;惊魂稍定&#xff0c;徒弟说:“师父啊师父&#…

NXP UWB NCJ29D5开发(一)环境搭建

1、从NXP的共享账号下载资料 共享账号需要找对接的NXP人员拿到&#xff0c;他会把资料分享到这个账号&#xff0c;在这个账号里面可以下载 进入nxp官网&#xff0c;登录后点击my nxp&#xff0c;选择Software Licensing and Support 进入后接着选择View accounts 进入后选择…

西瓜创客python编程进阶收费_西瓜创客和编程猫有什么不同?哪个更值得报名?...

看情况来决定即可&#xff0c;在课程内容上其实出入我觉得不是很大&#xff0c;重点是教学服务、师资、授课模式等&#xff0c;单纯我自己的角度来说&#xff0c;我个人偏向于西瓜创客多一点&#xff0c;他们家的课程更具有趣味性&#xff0c;游戏化教学&#xff0c;融入卡通人…

Stack的三种含义

作者&#xff1a;阮一峰 学习编程的时候&#xff0c;经常会看到stack这个词&#xff0c;它的中文名字叫做”栈”。 理解这个概念&#xff0c;对于理解程序的运行至关重要。容易混淆的是&#xff0c;这个词其实有三种含义&#xff0c;适用于不同的场合&#xff0c;必须加以区分。…

NXP UWB NCJ29D5开发(二)BlinkyLed例程

路径为UWB\NCJ29D5\NCJ29D5_CAS_Examples_v1.4\onic\BlinkyLed\toolsupport\keil 例程怎么来的可以看看上一篇NXP UWB NCJ29D5开发&#xff08;一&#xff09;环境搭建 1、 //系统选择外部晶振&#xff0c;时钟频率为55.2Mhz phscaAppHal_Init(PHSCA_APPHAL_XO_CLOCK_SOURCE_…

你要看透的56条人生哲理

当你踌躇不前、站在人生十字路口时候&#xff0c;这56条哲理或许能助你一臂之力&#xff01;      1&#xff0e;拿得起&#xff0c;放得下      我们每个人都有很多“宝贝”&#xff0c;但你不可能什么都得到&#xff0c;在某些时候一定要学会拿得起&#xff0c;放得下…

使用Spring和Java泛型简化数据访问层

1.概述 本文将着重于通过对系统中的所有实体使用单个通用的数据访问对象来简化DAO层 &#xff0c;这将导致优雅的数据访问 &#xff0c;而不会造成不必要的混乱或冗长。 2. Hibernate和JPA DAO 大多数生产代码库都有某种DAO层。 通常&#xff0c;实现范围从没有抽象基类的多个…

强肝保肝养肝4大食物

“强肝的食物,保肝的食物有哪些,养肝的食物有哪些”如果您对这些食物不了解不明白。那就看看专家为您推荐的四款强肝保肝养肝的食物。荔枝&#xff08;供图/华盖&#xff09;一、是荔枝&#xff0c;荔枝可以保肝&#xff0c;对肝有好处根据《本草纲目》记载荔枝有强肝健胰的效果…

如何查看注解实现_该怎么运用注解呢?Java团队元老有话说

来源 | 异步 15讲能学好诞生24年的JAVA吗&#xff1f;你当然会感到怀疑&#xff0c;众所周知&#xff0c;在技术向的IT论坛上&#xff0c;“如何在十天之内快速掌握好Java&#xff1f;”这类问题&#xff0c;往往会招来嘲笑。来源于知乎但在当下&#xff0c;5分钟能看完一部电影…

NXP S32K144开发(一)环境搭建和新建工程

1、首先需要安装S32 Design Studio for ARM&#xff0c;在NXP官网可以搜索到&#xff0c;这玩意也是基于eclipse的 安装好后就可以打开了。 2、新建工程 过程可以参考NXP官网&#xff1a; https://www.nxp.com/document/guide/get-started-with-the-s32k144evb:NGS-S32K144E…

首先记录异常的根本原因

Logback日志库的0.9.30版本带来了一个很棒的新功能&#xff1a;从根&#xff08;最内部&#xff09;异常而不是最外部异常开始记录堆栈跟踪。 当然&#xff0c;我的兴奋与我贡献了此功能无关。 用塞西尔德米勒&#xff08;Cecil B. de Mille&#xff09; 的话来解释&#xff1a…

成功醒言

成功醒言 C01 只有敢犯错误的人才能成事&#xff1b; 只有不犯同样错误的人才能成大事。 C02 固执≠执著&#xff1b; 幻想≠希望。 固执是无目标的执著&#xff1b; 执著是有目标的固执。 幻想是无法兑现的希望&#xff1b; 希望是有望实现的幻想。 固执地执著幻想&#xf…

Android 中的 Service 全面总结

1、Service的种类 按运行地点分类&#xff1a; 类别区别 优点缺点 应用本地服务&#xff08;Local&#xff09;该服务依附在主进程上&#xff0c; 服务依附在主进程上而不是独立的进程&#xff0c;这样在一定程度上节约了资源&#xff0c;另外Local服务因为是在同一进程因此不…

python基础学习1-三元表达式和lambda表达式

#!/usr/bin/env python # -*- coding:utf-8 -*- 三元运算 if else 的简写name "alex" if 11 else "SB" #如果条件成立 赋alex 否则 赋SB print(name)#--------------lambda表达式 f2 lambda a1,a2:a1a2100 #等价 下边函数定义 def f1(a1,a2): return …

怎么让存储过程通用化_怎么做分布式存储的面试?

cholerae 大神已经做了详细回答&#xff0c;http://zenlife.tk/interview-for-distributed-storage.md写于几年前&#xff0c;内容有点稚嫩&#xff0c;WAL辨识度很高, 其他问题一般.CAP不会再问了&#xff0c;专业的存储文献中很少(几乎不)提及CAP或PACELC, 这个词用于市场和销…

Java EE中的配置管理

我尝试配置管理在云计算中具有很多相关性 争论 较早。 实际上&#xff0c;我大胆地宣称配置管理是任何认真尝试从软件中节省几美元的基石。 那么什么是配置管理及其主要目标&#xff1f; 在不使事情变得过于复杂的情况下&#xff0c;我认为接下来的两个目标与事实相差不远。 以…

十年总结,一个JAVA人的十年人生路

十年总结-开篇&#xff1a;歇一歇&#xff0c;才能走的更远经常见坛子里有人问&#xff0c;学习java该如何入手&#xff0c;或者是该学java还是学XX语言。我一直觉得&#xff0c;编程跟语言关系不大&#xff0c;重点是要有解决问题的思路。学习一门语言&#xff0c;其实只是寻求…

(四)Qt实现自定义模型基于QAbstractTableModel (一般)

Qt实现自定义模型基于QAbstractTableModel 两个例子 例子1代码 Main.cpp #include <QtGui>#include "currencymodel.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);//数据源QMap<QString, double> currencyMap;currencyMap.insert(…

pt-query-digest使用介绍【转】

本文来自&#xff1a;http://isadba.com/?p651 一、pt-query-digest参数介绍. pt-query-digest --useranemometer --passwordanemometerpass --review h192.168.11.28,Dslow_query_log,tglobal_query_review \--history h192.168.11.28,Dslow_query_log,tglobal_query_re…