我正在尝试为以下代码编写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();
}
有人可以建议我如何重构原始方法以便更容易测试吗?
由于
答案 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()));
}