`

使用Guava Supplier Mock Datetime

阅读更多
通过下面的例子了解Guava Supplier的用法.在做单元测试的时候, 我们可能需要Mock掉一些对外部资源的依赖. 比如时间, 随机数, 系统文件访问.

下面是将要测试的代码, 将当前时间输出:
@Controller
@RequestMapping(value = "/time")
@VisibleForTesting
class TimeController {
 
	@RequestMapping(value = "/current", method = RequestMethod.GET)
	@ResponseBody
	public String showCurrentTime() {
		// BAD!!! Can't test
		DateTime dateTime = new DateTime();
		return DateTimeFormat.forPattern("hh:mm").print(dateTime);
	}
}


但是这里有一个问题, 就是代码中是直接new的一个DateTime对象, 所以造成了对系统时间的直接依赖. 导致我们对输出时间的测试比较困难, 因此这里我们要借助Guava Supplier.

Supplier只有一个方法: get(), 返回suppiler构建的对象. 比如下面的例子:
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 somewhere
		String firstName = UserUtilities.getUser().getFirstName();
		// more Guava
		if(isNullOrEmpty(firstName)) {
			value = DEFAULT_NAME;
		} else {
			value = firstName;
		}
	}
	 
	@Override
	public String get() {
		return value;
	}
}


通过上面的代码你将不再关心firstName是什么, 只需要调用get方法即可.


对目标代码进行重构

实现一个DateTime Supplier. 同时提供一个接口, 方便测试:
public interface DateTimeSupplier extends Supplier<DateTime> {
	DateTime get();
}


下面是具体实现
public class DateTimeUTCSupplier implements DateTimeSupplier {
	@Override
	public DateTime get() {
		return new DateTime(DateTimeZone.UTC);
	}
}


然后注入DateTimeSupplier:
@Controller
@RequestMapping(value = "/time")
@VisibleForTesting
class TimeController {
 
	@Autowired
	@VisibleForTesting
	// Injected DateTimeSupplier
	DateTimeSupplier dateTime;
	 
	@RequestMapping(value = "/current", method = RequestMethod.GET)
	@ResponseBody
	public 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;
	}
	 
	@Override
	public DateTime get() {
		return mockedDateTime;
	}
}


最后是测试代码:
public class TimeControllerTest {
 
	private final int HOUR_OF_DAY = 12;
	private final int MINUTE_OF_DAY = 30;
	 
	@Test
	public void testShowCurrentTime() throws Exception {
		TimeController controller = new TimeController();
		// Create the mock DateTimeSupplier with our known DateTime
		controller.dateTime = new MockDateTimeSupplier(new DateTime(2012, 1, 1, HOUR_OF_DAY, MINUTE_OF_DAY, 0, 0));
		 
		// Call our method
		String dateTimeString = controller.showCurrentTime();
		 
		// Using hamcrest for easier to read assertions and condition matchers
		assertThat(dateTimeString, is(String.format("%d:%d", HOUR_OF_DAY, MINUTE_OF_DAY)));
}
 
}


总体感觉代码还是比较多的, 又是接口又是实现的. 而目标就是为了对系统时间进行mock, 不过提供了一种单元测试的思路.

原文: http://java.dzone.com/articles/mocking-jodatimes-datetime-and
分享到:
评论
1 楼 Jen 2013-06-16  
用powermock 直接把静态方法mock掉应该能搞定的

相关推荐

    使用google guava 实现定时缓存功能

    使用google guava 实现定时缓存功能

    SpringBoot使用Guava实现日志脱敏

    Guava脱敏是指使用Google Guava库进行敏感数据的脱敏处理。脱敏是一种保护个人隐私和数据安全的技术,通过对敏感数据进行处理,将其转换为不敏感或匿名数据,以防止数据泄露和滥用。 在Guava中,脱敏通常涉及对字符...

    guava使用方法教程

    guava 使用方法 教程

    Guava使用培训教程

    Guava使用培训教程

    guava-17.0-API文档-中文版.zip

    赠送jar包:guava-17.0.jar; 赠送原API文档:guava-17.0-javadoc.jar; 赠送源代码:guava-17.0-sources.jar; 赠送Maven依赖信息文件:guava-17.0.pom; 包含翻译后的API文档:guava-17.0-javadoc-API文档-中文...

    guava源文档

    guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档...

    guava-23.0-API文档-中文版.zip

    赠送jar包:guava-23.0.jar; 赠送原API文档:guava-23.0-javadoc.jar; 赠送源代码:guava-23.0-sources.jar; 赠送Maven依赖信息文件:guava-23.0.pom; 包含翻译后的API文档:guava-23.0-javadoc-API文档-中文...

    eclipse-guava-插件

    eclipse的guava插件,使用guava toStringHelper造成toString函数。同样适用于hashcode equals 等

    guava-18.0-API文档-中文版.zip

    赠送jar包:guava-18.0.jar; 赠送原API文档:guava-18.0-javadoc.jar; 赠送源代码:guava-18.0-sources.jar; 包含翻译后的API文档:guava-18.0-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:...

    guava-20.0-API文档-中文版.zip

    赠送jar包:guava-20.0.jar; 赠送原API文档:guava-20.0-javadoc.jar; 赠送源代码:guava-20.0-sources.jar; 赠送Maven依赖信息文件:guava-20.0.pom; 包含翻译后的API文档:guava-20.0-javadoc-API文档-中文...

    不加密Google Guava视频教程.txt

    ├─Google Guava 第14讲-Guava之Closer使用和原理剖析,非常重要.wmv ├─Google Guava 第15讲-Base64原理详解,手动实现base64的Encoding.wmv ├─Google Guava 第16讲-Base64原理详解,手动实现base64的...

    guava-31.1-jre.jar

    guava

    guava-30.1.1-jre-API文档-中英对照版.zip

    赠送jar包:guava-30.1.1-jre.jar; 赠送原API文档:guava-30.1.1-jre-javadoc.jar; 赠送源代码:guava-30.1.1-jre-sources.jar; 赠送Maven依赖信息文件:guava-30.1.1-jre.pom; 包含翻译后的API文档:guava-30.1...

    guava-23.0.zip guava.jar guava

    guava-23.0.zip guava.jar guava

    guava-30.0-jre-API文档-中文版.zip

    赠送jar包:guava-30.0-jre.jar; 赠送原API文档:guava-30.0-jre-javadoc.jar; 赠送源代码:guava-30.0-jre-sources.jar; 赠送Maven依赖信息文件:guava-30.0-jre.pom; 包含翻译后的API文档:guava-30.0-jre-...

    guava-27.0.1-jre-API文档-中文版.zip

    赠送jar包:guava-27.0.1-jre.jar; 赠送原API文档:guava-27.0.1-jre-javadoc.jar; 赠送源代码:guava-27.0.1-jre-sources.jar; 赠送Maven依赖信息文件:guava-27.0.1-jre.pom; 包含翻译后的API文档:guava-...

    guava-16.0.1-API文档-中文版.zip

    赠送jar包:guava-16.0.1.jar; 赠送原API文档:guava-16.0.1-javadoc.jar; 赠送源代码:guava-16.0.1-sources.jar; 赠送Maven依赖信息文件:guava-16.0.1.pom; 包含翻译后的API文档:guava-16.0.1-javadoc-API...

    guava-28.2-jre-API文档-中文版.zip

    赠送jar包:guava-28.2-jre.jar; 赠送原API文档:guava-28.2-jre-javadoc.jar; 赠送源代码:guava-28.2-jre-sources.jar; 赠送Maven依赖信息文件:guava-28.2-jre.pom; 包含翻译后的API文档:guava-28.2-jre-...

    guava-22.0-API文档-中文版.zip

    赠送jar包:guava-22.0.jar; 赠送原API文档:guava-22.0-javadoc.jar; 赠送源代码:guava-22.0-sources.jar; 赠送Maven依赖信息文件:guava-22.0.pom; 包含翻译后的API文档:guava-22.0-javadoc-API文档-中文...

    重试框架spring-retry以及guava-retry的使用

    压缩包包含着springboot项目retry,项目中演示了使用spring-retry传统的方式以及注解的方式使用重试的案例,也有guava-retry的使用案例,以及两者的区别

Global site tag (gtag.js) - Google Analytics