存根类 测试代码 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;一个对…

注册服务号、订阅号流程

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

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

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

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

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

【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…

【APICloud系列|32】iOS 上架去除Icon图像中的alpha通道或透明度

上架的时候你们有没有遇到过这个问题?? 打开图片的“显示简介”,你会发现有个叫“alpha通道”的东西,(如果是“是”你的图片就不能上架)如下图: 第一种方法 怎样解决。把你的图片用PS打开,如下图选择进行操作:

网站如何快速搭建即时响应客服系统

首先简单说明一下情况&#xff0c;公司原来的网站是用微起点快速建站做的&#xff0c;几天就搭建完成啦&#xff0c;最近又原生开发了一个大数据网站。 自己在原来的网站搭建了一个客服系统&#xff0c;后来老板不喜欢&#xff0c;我又给取消啦。 直入主题啦 登录百度账号 选…

在NetBeans,Eclipse,IntelliJ,OpenShift和Maven上使用WildFly 9

WildFly 9 CR1是最近发布的。 包括许多很酷的功能&#xff1a; 智能负载均衡 HTTP / 2和SPDY支持 新的离线CLI模式 正常关闭单节点 新的仅Servlet发行版 而且这超出了通常的Java EE 7兼容性&#xff01; 该博客是一个快速检查&#xff0c;以验证它是否可以在所有三个主要…

【CSS】font样式简写(转)- 不是很建议简写

一、字体属性主要包括下面几个 font-family&#xff0c;font-style&#xff0c;font-variant&#xff0c;font-weight&#xff0c;font-size&#xff0c;fontfont-family&#xff08;字体族&#xff09;: “Arial”、“Times New Roman”、“宋体”、“黑体”等;font-style&…

Bluetooth LE(低功耗蓝牙) - 第一部分

前言 在写这篇文章的时候&#xff0c;谷歌刚刚发布了Android Wear &#xff0c;摩托罗拉也发布了 Moto 360 智能手表。Android Wear的API还是相当基本的&#xff0c;是很好的文档材料&#xff0c;而且还会不断的更新&#xff0c;所以我不打算写一个关于他们的教程&#xff08;至…

Android查看web日志,详解Android WebView监听console错误信息

根据需求&#xff0c;我们要拿到h5的错误信息&#xff0c;并将error信息进行上报。查询了下Android WebView的API发现了WebChromeClient这个方法可以满足要求&#xff1a;Overridepublic boolean onConsoleMessage(ConsoleMessage consoleMessage) {//获取log的级别switch (con…