在單元測試中有時候需要對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));
}
採用這種方式,構造函數就不用向單側場景妥協(本來就不應該妥協)。