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

存根类 测试代码 java

任何阅读此博客的人都可能已经意识到,目前我正在开发一个项目,其中包含大量的旧代码,这些旧代码庞大,扩展且编写时从未进行过任何测试。

在使用此遗留代码时,有一个行为非常差的类非常普遍,整个团队都在不时地跳闸。

为了保护这一罪恶,我将其称为X先生,尽管它的真名是SitePropertiesManager,因为它管理网站的属性。 表现不佳是因为:

  • 打破单一责任主体
  • 使用了由getInstance()工厂方法汇总的单例模式,
  • 有一个init()方法,必须在任何其他方法之前调用,
  • 通过直接访问数据库而不是使用DAO加载其数据,
  • 使用复杂的地图来存储其数据,
  • 访问文件系统以缓存数据库返回的数据
  • 有一个计时器来决定何时向上更新其缓存。
  • 是在泛型之前编写的,具有大量多余的findXXXX()方法。
  • 没有实现接口,
  • 使用了大量的复制和粘贴程序。

这使得在编写新代码的单元测试时很难创建存根,并使旧代码杂乱无章:

SitePropertiesManager propman = SitePropertiesManager.getInstance();

该博客介绍了处理尴尬字符的方法,并演示了如何为它们创建存根,同时消除了Singleton模式的影响。 与以前的“测试技术”博客一样,我的演示代码也基于“地址”网络应用示例 。

在本系列的其他博客中,我一直在演示如何测试AddressService,而这个博客也没有什么不同。 但是,在这种情况下, AddressService必须加载站点属性并决定是否返回地址,但是在查看之前,我首先需要使用书写不正确的SitePropertiesManager来使用。 但是,我不拥有该代码,因此我编写了一个特技双重版本,该版本打破了我能想到的许多规则。 我不会在这里让您感到厌烦,因为SitePropertiesManager的所有源代码都可以在以下位置找到:git://github.com/roghughe/captaindebug.git

如上所述,在这种情况下, AddressService使用站点属性来确定是否已启用它。 如果是,它将发送回一个地址对象。 我还将假装AddressService是一些使用站点属性静态工厂方法的旧代码,如下所示:

public Address findAddress(int id) {logger.info("In Address Service with id: " + id);Address address = Address.INVALID_ADDRESS;if (isAddressServiceEnabled()) {address = addressDao.findAddress(id);address = businessMethod(address);}logger.info("Leaving Address Service with id: " + id);return address;}private boolean isAddressServiceEnabled() {SitePropertiesManager propManager = SitePropertiesManager.getInstance();return new Boolean(propManager.findProperty("address.enabled"));}

驯服这种类型的类时,他要做的第一件事是停止使用getInstance()获取保持和一个对象,将其从上述方法中删除,并开始使用依赖项注入。 必须至少调用一次getInstance() ,但这可以在程序的启动代码中进行。 在Spring的世界中,解决方案是在Spring FactoryBean实现中包装一个表现不佳的类,该类成为应用程序中getInstance()的唯一位置–至少对于新代码/增强代码而言。

public class SitePropertiesManagerFactoryBean implementsFactoryBean {private static SitePropertiesManager propsManager = SitePropertiesManager.getInstance();@Overridepublic SitePropertiesManager getObject() throws Exception {return propsManager;}@Overridepublic Class getObjectType() {return SitePropertiesManager.class;}@Overridepublic boolean isSingleton() {return true;}
}

现在可以将其自动连接到AddressService类中:

@Autowiredvoid setPropertiesManager(SitePropertiesManager propManager) {this.propManager = propManager;}

但是,这些更改并不意味着我们可以为AddressService编写一些适当的单元测试,它们只是准备基础。 下一步是为SitePropertiesManager提取接口,使用eclipse可以轻松实现。

public interface PropertiesManager {public abstract String findProperty(String propertyName);public abstract String findProperty(String propertyName, String locale);public abstract List findListProperty(String propertyName);public abstract List findListProperty(String propertyName, String locale);public abstract int findIntProperty(String propertyName);public abstract int findIntProperty(String propertyName, String locale);}

在转移到接口时,我们还需要在Spring配置文件中手动配置SitePropertiesManager的实例,以便Spring知道将哪个类连接到哪个接口:

<beans:bean id="propman" class="com.captaindebug.siteproperties.SitePropertiesManager" />

我们还需要使用限定符更新AddressService的 @Autowired批注:

@Autowired@Qualifier("propman")void setPropertiesManager(PropertiesManager propManager) {this.propManager = propManager;}

通过一个接口,我们现在可以轻松编写一个简单的SitePropertiesManager存根:

public class StubPropertiesManager implements PropertiesManager {private final Map propMap = new HashMap();public void setProperty(String key, String value) {propMap.put(key, value);}@Overridepublic String findProperty(String propertyName) {return propMap.get(propertyName);}@Overridepublic String findProperty(String propertyName, String locale) {throw new UnsupportedOperationException();}@Overridepublic List findListProperty(String propertyName) {throw new UnsupportedOperationException();}@Overridepublic List findListProperty(String propertyName, String locale) {throw new UnsupportedOperationException();}@Overridepublic int findIntProperty(String propertyName) {throw new UnsupportedOperationException();}@Overridepublic int findIntProperty(String propertyName, String locale) {throw new UnsupportedOperationException();}
}

有了存根,很容易为使用存根并与数据库和文件系统隔离的AddressService编写单元测试

public class AddressServiceUnitTest {private StubAddressDao addressDao;private StubPropertiesManager stubProperties;private AddressService instance;@Beforepublic void setUp() {instance = new AddressService();stubProperties = new StubPropertiesManager();instance.setPropertiesManager(stubProperties);}@Testpublic void testAddressSiteProperties_AddressServiceDisabled() {/* Set up the AddressDAO Stubb for this test */Address address = new Address(1, "15 My Street", "My Town", "POSTCODE","My Country");addressDao = new StubAddressDao(address);instance.setAddressDao(addressDao);stubProperties.setProperty("address.enabled", "false");Address expected = Address.INVALID_ADDRESS;Address result = instance.findAddress(1);assertEquals(expected, result);}@Testpublic void testAddressSiteProperties_AddressServiceEnabled() {/* Set up the AddressDAO Stubb for this test */Address address = new Address(1, "15 My Street", "My Town", "POSTCODE","My Country");addressDao = new StubAddressDao(address);instance.setAddressDao(addressDao);stubProperties.setProperty("address.enabled", "true");Address result = instance.findAddress(1);assertEquals(address, result);}
}

所有这些都很笨拙,但是如果您无法提取接口会发生什么呢? 我将其保存另一天...

参考: Captain Debug博客上的 JCG合作伙伴 提供的用于遗留代码的存根-测试技术6

相关文章 :

  • 测试技巧–不编写测试
  • 端到端测试的滥用–测试技术2
  • 您应该对什么进行单元测试? –测试技术3
  • 常规单元测试和存根–测​​试技术4
  • 使用模拟的单元测试–测试技术5
  • 有关为旧版代码创建存根的更多信息–测试技术7
  • 为什么要编写单元测试-测试技巧8
  • 一些定义–测试技术9
  • 使用FindBugs产生更少的错误代码
  • 在云中开发和测试

翻译自: https://www.javacodegeeks.com/2011/11/creating-stubs-for-legacy-code-testing.html

存根类 测试代码 java

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

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

相关文章

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

昨晚收到一封来自百度的邮件 这里需要登录工业和信息化部查询后的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;一个对…

注册服务号、订阅号流程

进入微信公众平台,选择注册类型,订阅号/服务号 填写基本信息 选择类型 选择订阅号或者服务号

sql并发 锁 优化思路_并发优化–减少锁粒度

sql并发 锁 优化思路在高负载多线程应用程序中&#xff0c;性能非常重要。 开发人员必须意识到并发问题才能获得更好的性能。 当我们需要并发时&#xff0c;我们通常拥有必须由两个或更多线程共享的资源。 在这种情况下&#xff0c;我们处于竞争状态 &#xff0c;其中只有一个线…

c语言 指针到字符串,C语言中的指针和字符串

前言务必理解指针与内存模型&#xff0c;不要死记硬背。内存里的字符串C语言中的字符串一般是char *类型的&#xff0c;这是怎样存在内存中的呢&#xff1f;cchar *s "NIHAO";| s:400 ||---|---|---|---||N|I|H|A|O| 0 ||---|---|---|---|---|---||400|401|402|403|…

【APICloud系列|33】移动应用软件加固步骤,适合所有的安卓应用市场

在腾讯开放平台下载应用加固工具legutools 下载安装打开 点击获取API密钥。链接: https://cloud.tencent.com/developer/article/1385239 一、登录腾讯云账号

Openjudge-计算概论(A)-放苹果

描述&#xff1a; 把M个同样的苹果放在N个同样的盘子里&#xff0c;允许有的盘子空着不放&#xff0c;问共有多少种不同的分法&#xff1f;&#xff08;用K表示&#xff09;5&#xff0c;1&#xff0c;1和1&#xff0c;5&#xff0c;1 是同一种分法。输入第一行是测试数据的数目…

c语言程序设计徐立辉答案,C语言程序设计 牛志成,徐立辉,刘冬莉著 清华大学出版社 9787302165620...

商品描述&#xff1a;【图书描述】:本书以2008年等级考试新需求为出发点&#xff0c;教学环境升级到了VC6&#xff0e;0平台。特别着重解决当前C语言教学中存在的一些问题和矛盾&#xff0c;在教学内容体系改革、教学过程组织、应对等级考试需要和素质教学实施等多个方面进行了…

怎么把图片内存变小尺寸保持不变呢。

在好多应用平台要求尺寸多少*多少&#xff0c;大小<50kb. 缩小图片的内存占用&#xff0c;但尺寸即分辨率不变&#xff0c;可以改变压缩的质量来实现。下面以PS为例&#xff1a; 1、用PS打开图片&#xff0c;然后选择文件菜单里的存储为&#xff0c;格式选择png。 2、选择…

C#vs Java哪一个更快? 将25k C#转换为Java(2)

在上一篇文章中&#xff0c;我描述了如何将25k行C&#xff03;转换为Java以及从该练习中学到的教训。 我收到以下问题&#xff1a; 顺便说一句很棒的文章。 迁移代码后&#xff0c;性能与C&#xff03;版本相比如何&#xff1f; 改写系统的动机之一是使系统变得更快&#xff…

将 改为c语言表达式,基于c语言表达式求解课程设计修改.doc

基于c语言表达式求解课程设计修改摘 要通过数据结构这门课程&#xff0c;我们较深入的了解到了栈&#xff0c;栈是一种重要的线性结构&#xff0c;它广泛应用于各种软件系统中&#xff0c;因此在面向对象的程序设计中&#xff0c;它们是多型数据类型。本次试验我们将探索表达式…

【Java必备资料包】

适合所有大厂java开发工场师。 链接&#xff1a;https://pan.baidu.com/s/1wRxRDCGvex_G2aCZ6W57vw 提取码&#xff1a;e9xu

SaaS系列介绍之十一: SaaS商业模式分析

1 配置模式 中国企业很多是人治&#xff0c;管理弹性非常大&#xff0c;公司的政策经常变化&#xff0c;管理流程、业务变化也非常大&#xff0c;发展也非常快;一个公司今年是10个人&#xff0c;明年是100个人&#xff0c;后年可能是1000人。管理机制、方法处于经常变化的状态&…

真机x86 android分辨率,Android-x86入门之--启动参数设置

之前的文章里面我也有提到分辨率的设置&#xff0c;这里就详细说下。Android-x86启动的时候有四个选项&#xff0c;大家都知道&#xff0c;第一个是高密度&#xff0c;第二个是低密度&#xff0c;两个启动之后的效果是不一样的&#xff0c;一个图标大&#xff0c;一个小&#x…