日期检查的基本JUnit

时间:2014-07-17 13:37:23

标签: java date junit

我正在尝试为以下代码编写Junit;

/**
 * Check if a date is greater than 24 hours
 * @param dateToCheck the date to check
 * @return true if it is greater than otherwise false
 */
public static boolean dateGreaterThan24Hours(Date dateToCheck){
    if(dateToCheck == null){
        throw new IllegalArgumentException("The date passed to check for greater than 24 hours is null");
    }
    long millisIn24Hours = 1000 * 60 * 60 * 24;
    Date hours24ago = new Date(new Date().getTime() - millisIn24Hours);
    if (dateToCheck.before(hours24ago)) {
        //24 hrs have passed
        return true;
    }
    return false;
}

但是我很难这样做,因为该方法只接受一个日期来检查。意味着当前对测试方法的尝试显然会失败;

@Test
public void checkLessThan24HoursShouldReturnTrue(){
    //Calendar represents the 7th of July 2014 at 17.30pm
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, 2014);
    cal.set(Calendar.MONTH, 07);
    cal.set(Calendar.DAY_OF_MONTH, 7);
    cal.set(Calendar.HOUR_OF_DAY,17);
    cal.set(Calendar.MINUTE,30);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.MILLISECOND,0);

    Date july7 = cal.getTime();

    //Calendar represents the 6th of July 2014 at 18.30pm
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, 2014);
    cal.set(Calendar.MONTH, 07);
    cal.set(Calendar.DAY_OF_MONTH, 6);
    cal.set(Calendar.HOUR_OF_DAY,18);
    cal.set(Calendar.MINUTE,30);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.MILLISECOND,0);

    Date july6 = cal.getTime();
}

有人可以建议我如何重构原始方法以便更容易测试吗?

由于

3 个答案:

答案 0 :(得分:5)

您无需更改原始方法。最容易编写的测试是:

@Test
public void checkMoreThan24HoursShouldReturnTrue() {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.HOUR_OF_DAY, -25);
    assertTrue(YourClass.dateGreaterThan24Hours(cal.getTime()));
}

@Test
public void checkLessThan24HoursShouldReturnFalse() {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.HOUR_OF_DAY, -23);
    assertFalse(YourClass.dateGreaterThan24Hours(cal.getTime()));
}

另外,我会建议@DaveNewton在评论中建议的一些重构,以及验证null参数的自定义异常的测试。

答案 1 :(得分:0)

如果您可以使用新的Java 8 Classes(或JodaTime),您可以编写更清晰的代码。

另外,根据您希望24小时前的原因,可能会有关于夏令时的错误,因为您只需要24小时毫秒,而某些日子可能不是一整天。

以下是使用新Java 8时间库的等效代码。我将该方法重命名为更具意图,并添加了Clock可选参数,允许您设置测试时间:

public static boolean checkDateMorethan24HrsOld(Date dateToCheck){
    return checkDateMorethan24HrsOld(dateToCheck, Clock.systemDefaultZone());
}

public static boolean checkDateMorethan24HrsOld(Date dateToCheck, Clock clock){
    if(dateToCheck == null){
        //maybe throw NullPointerInstead?
        throw new IllegalArgumentException("The date is null");
    }
    Objects.requireNonNull(clock);
    //use clock.instant().minus(Period.ofDays(1)) to support DST
    Instant time24HrsAgo =clock.instant().minus(Duration.ofHours(24));
    return dateToCheck.toInstant().compareTo(time24HrsAgo) <0;

}

然后你的测试:

@Test
public void checkLessThan24HoursShouldReturnTrue(){

    Instant clocktime = Instant.parse("2014-07-07T17:30:00Z");
    Clock clock =Clock.fixed(clocktime, ZoneId.systemDefault());

    assertTrue(checkDateMorethan24HrsOld(Date.from(clocktime.minus(Duration.ofDays(2))), clock));
    assertFalse("exactly 24 hrs ago",
                    checkDateMorethan24HrsOld(Date.from(clocktime.minus(Duration.ofDays(1))), clock));

    assertFalse(checkDateMorethan24HrsOld(Date.from(clocktime.minus(Duration.ofHours(1))), clock));

}

当然,如果方法采用Instant代替Date,则此代码更简单。

答案 2 :(得分:0)

如果您可以重构代码以便测试友好:

static final long millisIn24Hours = 1000 * 60 * 60 * 24;

public static boolean dateGreaterThan24Hours(Date dateToCheck){
    return dateGreaterThan(dateToCheck, 
            Calendar.getInstance().getTime(), - millisIn24Hours);
}

public static boolean dateGreaterThan(Date date, Date than, long msDiff) {
    if(date == null){
        throw new IllegalArgumentException("date is null");
    }
    if(than == null){
        throw new IllegalArgumentException("than is null");
    }
    return date.before(new Date(than.getTime() + msDiff));
}

你可以这样:

public void testDateGreaterTrue() {
    Date now = new Date();
    assertFalse(dateGreaterThan(now, 
            new Date(now.getTime()-millisIn24Hours), millisIn24Hours));
}

public void testDateGreaterFalse() {
    Date now = new Date();
    assertFalse(dateGreaterThan(now, 
            new Date(now.getTime()-millisIn24Hours-1), millisIn24Hours));
}

而不是:

public void testDateGreaterThan24HoursTrue() {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) - 25);
    assertTrue(dateGreaterThan24Hours(cal.getTime()));
}

public void testDateGreaterThan24HoursFalse() {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) - 23);
    cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 59);
    cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + 59);
    assertFalse(dateGreaterThan24Hours(cal.getTime()));
}