Writing and testing convenience methods using Java 8 Date/Time classes

后端 未结 1 1674
粉色の甜心
粉色の甜心 2020-11-28 17:13

I have some old convenience methods, written using Calendars, that I want to update to use the Java.time.* classes introduced in Java 8. Some of the methods in my class get

相关标签:
1条回答
  • 2020-11-28 17:29

    In your test (and only during test!) set the clock that your convenience class uses so that you can predict the desired/expected results independently of the computer clock:

    public class ConvenienceTest {
    
        @Test
        public void testGetLocalHour() {
            Convenience underTest = new Convenience();
    
            ZoneId zone = ZoneId.of("America/Los_Angeles");
    
            ZonedDateTime fixedZdt = ZonedDateTime.now(zone).withHour(0);
            underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
            assertEquals("24", underTest.getLocalHour24HourClock());
    
            fixedZdt = fixedZdt.withHour(1);
            underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
            assertEquals("01", underTest.getLocalHour24HourClock());
    
            fixedZdt = fixedZdt.withHour(23);
            underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
            assertEquals("23", underTest.getLocalHour24HourClock());
    
            // TODO test with other time zones
        }
    
    }
    

    For this to work it of course requires that your convenience class can accept a Clock and uses it:

    public class Convenience {
    
        private Clock clock = Clock.systemDefaultZone();
    
        /** For testing only. Sets the clock from which to get the time. */
        void setClock(Clock clockForTest) {
            this.clock  = clockForTest;
        }
    
        public String getLocalHour24HourClock() {
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("kk");
            ZonedDateTime zdt = ZonedDateTime.now(clock);
            return zdt.format(fmt);
        }
    
    }
    

    With this implementation the tests just passed on my computer.

    Stepping a step back: if your convenience methods are but a thin layer on top of java.time, you may start to consider how much value a unit test has. If it is doing some real work (like formatting in the above example, something that regularly goes wrong), a test is valuable, but if a method just returns a value from a single call into java.time, you may not need a test. You shouldn’t test java.time, preferably only your own code.

    0 讨论(0)
提交回复
热议问题