使用Guava Supplier Mock Datetime
通过下面的例子了解Guava Supplier的用法.在做单元测试的时候, 我们可能需要Mock掉一些对外部资源的依赖. 比如时间, 随机数, 系统文件访问.
下面是将要测试的代码, 将当前时间输出:
@Controller@RequestMapping(value = "/time")@VisibleForTestingclass TimeController { @RequestMapping(value = "/current", method = RequestMethod.GET)@ResponseBodypublic String showCurrentTime() {// BAD!!! Can't testDateTime dateTime = new DateTime();return DateTimeFormat.forPattern("hh:mm").print(dateTime);}}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;}}public interface DateTimeSupplier extends Supplier<DateTime> {DateTime get();}public class DateTimeUTCSupplier implements DateTimeSupplier {@Overridepublic DateTime get() {return new DateTime(DateTimeZone.UTC);}}@Controller@RequestMapping(value = "/time")@VisibleForTestingclass TimeController { @Autowired@VisibleForTesting// Injected DateTimeSupplierDateTimeSupplier dateTime; @RequestMapping(value = "/current", method = RequestMethod.GET)@ResponseBodypublic String showCurrentTime() {return DateTimeFormat.forPattern("hh:mm").print(dateTime.get());}}public class MockDateTimeSupplier implements DateTimeSupplier { private final DateTime mockedDateTime; public MockDateTimeSupplier(DateTime mockedDateTime) {this.mockedDateTime = mockedDateTime;} @Overridepublic DateTime get() {return mockedDateTime;}}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)));} }