在单元测试中有时候需要对domain的时间属性进行测试,比如:domain否过期。为了某些场景的单元测试,有时需要在构造函数中暴露时间参数,但这种做法总有种小题大做的味道。使用
DateTimeUtils
就可以修改系统当前时间,不用暴露时间参数,就可以完成该场景单元测试。
1. 之前设计
domain:Information,构造函数如下所示,该信息一天后失效。
public Information(String context,DateTime createAt) {
this.id = IdGenerator.nextId();
this.context = context;
this.createdAt = createAt;
this.expiredAt = createdAt.plusDays(1);
}
假设单元测试要测试:当前信息是否过期。
@Test
public void test_information_is_expired() throws Exception {
Information information = new Information("information",Datetime.now().minusDays(2))
assertThat(information.getExpiredAt.isBeforeNow(), is(true));
}
当然,真正的单元测试肯定不会这么简单。在单侧中直接通过 createAt
创建了个两天前的 information
,后面断言对象过期了。其实在实际生产环境中, createAt
属性的值是可以不用外界传入的。仅仅为了单测暴露,着实有点小题大做。
2. 使用DateTimeUtils
这个类中有两个方法,在单侧中使用这两个方法就能完成系统时间修改。
public static final void setCurrentMillisFixed(long fixedMillis)
作用:将系统当前时间设置成一个固定时间。
public static final void setCurrentMillisSystem()
作用:恢复系统当前时间
新的domian:
public Information(String context) {
this.id = IdGenerator.nextId();
this.context = context;
this.createdAt = DateTime.now(UTC);
this.expiredAt = createdAt.plusDays(1);
}
同样场景下的单侧:
@Test
public void test_information_is_expired() throws Exception {
//将当前系统时间设置成3天前
DateTimeUtils.setCurrentMillisFixed(now(UTC).minusDays(3).getMillis());
// 创建domain
Information information = new Information("information")
// 恢复系统时间
DateTimeUtils.setCurrentMillisSystem();
// 将过期时间与当前时间进行比较
assertThat(information.getExpiredAt.isBeforeNow(), is(true));
}
采用这种方式,构造函数就不用向单侧场景妥协(本来就不应该妥协)。