Mocking time in Java 8's java.time API

后端 未结 8 1550
我寻月下人不归
我寻月下人不归 2020-11-27 16:09

Joda Time has a nice DateTimeUtils.setCurrentMillisFixed() to mock time.

It\'s very practical in tests.

Is there an equivalent in Java 8\'s java.time API

相关标签:
8条回答
  • 2020-11-27 17:01

    The closest thing is the Clock object. You can create a Clock object using any time you want (or from the System current time). All date.time objects have overloaded now methods that take a clock object instead for the current time. So you can use dependency injection to inject a Clock with a specific time:

    public class MyBean {
        private Clock clock;  // dependency inject
        ...
        public void process(LocalDate eventDate) {
          if (eventDate.isBefore(LocalDate.now(clock)) {
            ...
          }
        }
      }
    

    See Clock JavaDoc for more details

    0 讨论(0)
  • 2020-11-27 17:03

    I used a new class to hide the Clock.fixed creation and simplify the tests:

    public class TimeMachine {
    
        private static Clock clock = Clock.systemDefaultZone();
        private static ZoneId zoneId = ZoneId.systemDefault();
    
        public static LocalDateTime now() {
            return LocalDateTime.now(getClock());
        }
    
        public static void useFixedClockAt(LocalDateTime date){
            clock = Clock.fixed(date.atZone(zoneId).toInstant(), zoneId);
        }
    
        public static void useSystemDefaultZoneClock(){
            clock = Clock.systemDefaultZone();
        }
    
        private static Clock getClock() {
            return clock ;
        }
    }
    
    public class MyClass {
    
        public void doSomethingWithTime() {
            LocalDateTime now = TimeMachine.now();
            ...
        }
    }
    
    @Test
    public void test() {
        LocalDateTime twoWeeksAgo = LocalDateTime.now().minusWeeks(2);
    
        MyClass myClass = new MyClass();
    
        TimeMachine.useFixedClockAt(twoWeeksAgo);
        myClass.doSomethingWithTime();
    
        TimeMachine.useSystemDefaultZoneClock();
        myClass.doSomethingWithTime();
    
        ...
    }
    
    0 讨论(0)
提交回复
热议问题