2

I have the following method which take a UNIX time stamp and returns the age in terms of days, hours, or minutes. I want to unit test it with JUnit but I'm unsure how I would start doing that as the current time is constantly changing. Any advice? Thanks!

Here is the method:

public static String getAge(long unixTime) throws Exception {
        long diff = (System.currentTimeMillis() / 1000) - unixTime;
    diff = diff / 60;
    if (diff < 60) {
        return Math.round(diff) + " m";
    }
    else
        diff /= 60;
    if (diff < 24) {
        return Math.round(diff) + " h";
    }
    else {
        diff /= 24;
        return Math.round(diff) + " d";
    }

}

DM5963
  • 103
  • 6
  • Use a [`Clock`](https://docs.oracle.com/javase/9/docs/api/java/time/Clock.html) for obtaining “current time”. In test, supply a `Clock` with known “current time” so you know which result to expect. In production use the system clock so you obtain the real time. – Ole V.V. Jan 26 '19 at 15:57
  • I don’t think `Math.round(diff)` has any effect on a `long`. – Ole V.V. Jan 26 '19 at 16:00
  • Possible duplicate of [Writing and testing convenience methods using Java 8 Date/Time classes](https://stackoverflow.com/questions/52956373/writing-and-testing-convenience-methods-using-java-8-date-time-classes). In any case I believe that that question and my answer to it will be very helpful for you. – Ole V.V. Jan 27 '19 at 19:39

2 Answers2

0

Either you should change the design of a method to accept both current time and unixTime or you have to step back from pure JUnit and use PowerMock to mock System.currentTimeMillis() to return the result needed.

mergoth
  • 71
  • 1
  • 6
0

I would build a unix timestamp in my unitTest based on the current time. The granularity of the result of the method is coarse enough that a few millisecond difference between when you create the argument and when this method is executed will not be material. Granted, you will need to steer clear of the boundary conditions, i.e., a unixTime at 60 minutes and 24 hours.

public void testMinutes() {
    Instant minutesAgo = Instant.ofEpochMilli(System.currentTimeMillis() - 15 * 60 * 1000);
    String result = getAge(minutesAgo.getEpochSecond());
    assertSomething...
}

And so on for hours and days tests.

John Camerin
  • 677
  • 5
  • 15