与JodaTime的DateTime和Google Guava的供应商嘲笑

介绍

如果您是经验丰富的单元测试人员,那么当您看到任何与时间并发性随机性持久性磁盘I / O协同工作的代码时,您就会学会做笔记。

原因是测试可能非常脆弱,有时完全无法正确测试。 这篇文章将展示如何通过向消费者注入替代品来提取“时间”。 这篇文章将使用Spring 3作为Dependency Injection容器,尽管Guice ,其他DI容器或POJO上的构造器/设置器也可以使用。 我也将忽略Locales,因为重点在于DateTime的注入,而不是DateTime本身。

现有代码

您已经获得了一段代码进行单元测试(或者您正在创建一个代码,这是您的第一次尝试)。 我们的第一段代码,只有一个类:(该类是Spring 3.1控制器,其目的是作为String返回当前时间)

@Controller
@RequestMapping(value = '/time')
@VisibleForTesting
class TimeController {@RequestMapping(value = '/current', method = RequestMethod.GET)@ResponseBodypublic String showCurrentTime() {// BAD!!! Can't testDateTime dateTime = new DateTime();return DateTimeFormat.forPattern('hh:mm').print(dateTime);}
}

请注意,该类在该类中执行“新的DateTime()”。 这是相应的测试类:

我们进行测试会怎样? 假设我们有一台非常慢的机器怎么样。 您可能(并且很可能会)以比较DateTime与返回的DateTime不同 。 这是个问题!

首先要做的是删除依赖关系,但是我们该怎么做呢? 如果我们将DateTime设置为类的一个字段,我们仍然会遇到同样的问题。 介绍Google Guava的供应商界面。

Google Guava供应商

Supplier接口只有一个方法“ get()”,它将返回设置了任何供应商的实例。 例如,如果用户已登录,则供应商将返回用户的名字,如果尚未登录,则返回默认用户名:

public class FirstNameSupplier implements Supplier<String> {private String value;private static final String DEFAULT_NAME = 'GUEST';public FirstNameSupplier() {// Just believe that this goes and gets a User from somewhereString firstName = UserUtilities.getUser().getFirstName();// more Guavaif(isNullOrEmpty(firstName)) {value = DEFAULT_NAME;} else {value = firstName;}}@Overridepublic String get() {return value;}
}

对于您的实现方法,您并不在乎名字是什么,而只是得到一个名字。

重构DateTime

让我们继续。 有关使用Supplier的更真实的示例(以及本文的要点),让我们实现一个DateTime供应商,以将当前的DateTime还给我们。 在此过程中,我们还创建一个接口,以便我们可以创建模拟实现以进行测试:

public interface DateTimeSupplier extends Supplier<DateTime> {DateTime get();
}

一个实现:

public class DateTimeUTCSupplier implements DateTimeSupplier {@Overridepublic DateTime get() {return new DateTime(DateTimeZone.UTC);}
}

现在,我们可以使用DateTimeUTCSupplier并将其注入需要当前DateTime作为DateTimeSupplier接口的代码中:

@Controller
@RequestMapping(value = '/time')
@VisibleForTesting
class TimeController {@Autowired@VisibleForTesting// Injected DateTimeSupplierDateTimeSupplier dateTime;@RequestMapping(value = '/current', method = RequestMethod.GET)@ResponseBodypublic String showCurrentTime() {return DateTimeFormat.forPattern('hh:mm').print(dateTime.get());}
}

为了测试这一点,我们需要创建一个MockDateTimeSupplier并有一个控制器传递要返回的特定实例:

public class MockDateTimeSupplier implements DateTimeSupplier {private final DateTime mockedDateTime;public MockDateTimeSupplier(DateTime mockedDateTime) {this.mockedDateTime = mockedDateTime;}@Overridepublic DateTime get() {return mockedDateTime;}
}

请注意,要保存的对象是通过构造函数传递的。 这不会使您获得当前的日期/时间,但是会返回您想要的特定实例

最后是我们的测试(略微)行使了我们上面实现的TimeController的测试:

public class TimeControllerTest {private final int HOUR_OF_DAY = 12;private final int MINUTE_OF_DAY = 30;@Testpublic void testShowCurrentTime() throws Exception {TimeController controller = new TimeController();// Create the mock DateTimeSupplier with our known DateTimecontroller.dateTime = new MockDateTimeSupplier(new DateTime(2012, 1, 1, HOUR_OF_DAY, MINUTE_OF_DAY, 0, 0));// Call our methodString dateTimeString = controller.showCurrentTime();// Using hamcrest for easier to read assertions and condition matchersassertThat(dateTimeString, is(String.format('%d:%d', HOUR_OF_DAY, MINUTE_OF_DAY)));}}

结论

这篇文章展示了如何使用Google Guava的Supplier接口抽象出DateTime对象,以便您在考虑单元测试的情况下更好地设计实现! 供应商是解决“只给我一些东西”的好方法,请注意,这是已知的某种东西。

祝您编程愉快,别忘了分享!

参考:在Mike的网站博客上,从我们的JCG合作伙伴 Mike 嘲笑JodaTime的DateTime和Google Guava的供应商 。


翻译自: https://www.javacodegeeks.com/2012/10/mocking-with-jodatimes-datetime-and.html

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

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

相关文章

栈实现 C语言

最近上来写了一下栈&#xff0c;理解数据结构的栈。 头文件&#xff1a;stack.h 初始化栈结构与函数定义&#xff1a; #include<stdlib.h> #include <stdio.h> #include<memory.h> #define N 100struct stack {int data[N];int top;//标识栈顶 }; typedef s…

php签名墙,肺功能检查质量控制网

2017年12月2日&#xff0c;由中华医学会呼吸病学分会/儿科分会、国家呼吸系统疾病临床医学研究中心、国家呼吸疾病医疗质量控制中心、中国肺功能联盟、中国儿童肺功能协作组主办&#xff0c;浙江省中医院承办的"2017年中国肺功能检查规范化培训及应用推广学习班暨肺功能检…

餐饮水单打印软件_开发一款餐饮手机app系统软件什么价格?有哪些方面需要考虑?...

开发一款餐饮手机app系统软件什么价格&#xff1f;有哪些方面需要考虑&#xff1f;近年来&#xff0c;餐饮类的APP如雨后春笋般快速增长&#xff0c;无论是上档次的酒店&#xff0c;还是各大餐厅&#xff0c;都有各自的专属APP。餐饮APP的开发能让大型酒店/餐厅获得更多盈利、销…

html5中如何去掉input type date默认

html5中如何去掉input type date默认样式 2.对日期时间控件的样式进行修改目前WebKit下有如下9个伪元素可以改变日期控件的UI&#xff1a;::-webkit-datetime-edit – 控制编辑区域的::-webkit-datetime-edit-fields-wrapper – 控制年月日这个区域的::-webkit-datetime-edit-…

Spring-framework应用程序启动loadtime源码分析笔记(二)——@Transactional

Transactional标识类或方法&#xff0c;使方法被执行时使用事务方式执行&#xff0c;这里只讨论PROXY方法增强方法。使用EnableTransactionManagement&#xff0c;默认modelAdviceMode.PROXY&#xff0c;通过Import(TransactionManagementConfigurationSelector.class)来判断在…

具有Spring的简单工作流引擎

几个月前&#xff0c;在处理一个公司项目时&#xff0c;我们需要开发REST服务&#xff0c;该服务用于根据客户端应用程序发送的数据发送电子邮件。 在开发此服务期间&#xff0c;我们决定创建简单的工作流引擎&#xff0c;该引擎将为发送电子邮件收费&#xff0c;但该引擎也可用…

php put 参数,php – 如何在Guzzle 5中发送PUT请求的参数?

根据the manual,The body option is used to control the body of an entity enclosingrequest (e.g., PUT, POST, PATCH).记录的put’ing方法是&#xff1a;$client new GuzzleHttp\Client();$client->put(http://httpbin.org, [headers > [X-Foo > Bar],body > …

TypeScript学习笔记归纳(持续更新ing)

文章目录 前言 二、TypeScript的优势体现在哪里&#xff1f; 1、执行时间上的区别 2、基础数据类型区别 3、TS优势 三、TypeScript的关键特性 四、TypeScript的类型系统 1、什么是类型注释&#xff1f; 2、类型系统核心 - 常用类型 1&#xff09; 基本类型&#xff0…

组态王 6.55 启停plc_永宏PLC在远程控制系统中的应用

一、行业介绍本远程控制系统是给石药集团的下属子公司设计的一个控制方案。主要是配套GPRS-DTU产品实现远程plc与plc之间的数据共享。从而达到远程无线数据写入控制和读取监控的目的。二、客户需求(1) 客户可以在监控室控制至少2-3公里外的井上两个水泵的启动和停止。(2) 客户可…

Vue表格中,对数据进行转换、处理

众所周知&#xff0c;后端从Mysql取出的数据&#xff0c;一般是很难单独处理某一个Key的数据的&#xff08;需要处理的话&#xff0c;可能会浪费大量的性能。而且对页面加载时间有很大的影响&#xff09;&#xff0c;所以&#xff0c;从数据库取出的数据。只能由前端进行处理。…

Java应用程序中的SQL注入

在本文中&#xff0c;我们将讨论什么是SQL注入攻击。 以及它如何影响任何Web应用程序使用后端数据库。 在这里&#xff0c;我专注于Java Web应用程序。 开放Web应用程序安全项目&#xff08;OWAP&#xff09;列出了SQL注入是Web应用程序的主要漏洞攻击。 黑客将Web请求中的SQL代…

【转】ReactNativeweexDeviceOne对比

React Native出来有一段时间了&#xff0c;国内的weex和deviceone是近期发布的&#xff0c;我可以说从2011年就开始关注快速开发的跨平台平台技术了&#xff0c;接触过phoneGap、数字天堂、appcan等早期的移动中间件技术&#xff0c;也跟朋友也讨论过这类的轻量级框架。这些年通…

bluetooth射频已关闭请打开bluetooth射频_希杰大功率射频放大器烧了维修诊断步骤...

如果电阻值过低&#xff0c;说明电源内部存在短路&#xff0c;正常时其阻值应能达到100千欧以上;电容器应能够充放电&#xff0c;如果损坏&#xff0c;则表现为AC电源线两端阻值低&#xff0c;呈短路状态&#xff0c;否则可能是开关管击穿。然后检查直流输出部分脱开负载&#…

java中整数如何表示,在Java中如何在位级别上内部表示整数?

慕瓜9086354Java整数为32位&#xff0c;并且总是带符号的。这意味着&#xff0c;最高有效位(MSB)用作符号位。用an表示的整数int不过是位的加权和。权重分配如下&#xff1a;Bit# Weight31 -2^3130 2^3029 2^29... ...2 2^21 2^10 …

洛谷-P1160 队列安排

题目 Problem Description 一个学校里老师要将班上N个同学排成一列&#xff0c;同学被编号为1&#xff5e;N&#xff0c;他采取如下的方法&#xff1a; 1.先将1号同学安排进队列&#xff0c;这时队列中只有他一个人&#xff1b; 2.2&#xff5e;N号同学依次入列&#xff0c;编号…

1.HTML小结

HTML 基本文档 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>文档标题</title> </head> <body> 可见文本... </body> </html> <!DOCTYPE html>html文件声明。charset"UTF-8…

方法参数名称和Spring

继续之前的博客文章有关构造函数和方法参数以及Java在运行时不保留参数名称的情况–先前的文章涉及构造函数不保留参数名称及其对Spring中的Contructor注入的含义&#xff0c;在此我将介绍更多内容不保留参数名称的情况对Spring有影响&#xff1a; 1.考虑带参数的Spring MVC C…

Fragment Or DialogFragment Can not perform this action after onSaveInstanceState

转载&#xff1a;http://blog.csdn.net/chenshufei2/article/details/48747149 public void show(FragmentManager manager, String tag) {mDismissed false;mShownByMe true;FragmentTransaction ft manager.beginTransaction();ft.add(this, tag);ft.commit(); //注意这里…

php延迟更新,ThinkPHP开发指南-模型-高级模型之延迟更新

导航&#xff1a;上一页我们经常需要给某些数据表添加一些需要经常更新的统计字段&#xff0c;例如用户的积分、文件的下载次数等等&#xff0c;而当这些数据更新的频率比较频繁的时候&#xff0c;数据库的压力也随之增大不少&#xff0c;我们可以利用高级模型的延迟更新功能缓…

three.js制作3d模型工具_3D打印模型打磨抛光常用工具

对于追求更好模型品质的人来说&#xff0c;对3D打印模型进行后处理工作是必不可少的&#xff0c;而后处理&#xff0c;首要的便是对模型进行打磨、抛光&#xff0c;将不属于模型的耗材去除&#xff0c;提高表面光洁度。在此工作中&#xff0c;我们需要用到很多工具&#xff0c;…