2014-01-06 52 views
14

爲了測試時間相關的代碼這是很好的使用Virtual Clock Pattern在測試中使用DateTimeUtils.setCurrentMillisFixed安全嗎?

的想法是,我們拉當前時間不使用new Date,但可與虛擬時鐘返回預定的固定時間被嘲笑的時鐘。

現在,在Java中,我們有JodaTime與DateTime類和允許設置的採樣時間與

DateTimeUtils.setCurrentMillisFixed(today.getMillis()); 

和固定時間重置爲系統時間:

DateTimeUtils.setCurrentMillisSystem(); 

這裏是一個good article關於如何將它與TestNG一起使用。

現在的問題!

如果在全局上下文中爲運行測試時間設置全局上下文中的固定時間,那麼將此技術與setUp和tearDown方法一起使用有多安全。只要我得到它 - 只要我們沒有兩個並行測試,並行運行在相同環境中的這種技術,它就會工作。

+3

如果您使用threeten([jodatime的後繼](http://stackoverflow.com/a/4633326/829571))或java 8,則有一個內置的['Clock'類用於此目的](http ://download.java.net/jdk8/docs/api/java/time/Clock.html) – assylias

+0

正如您所說的,並行運行測試並不可靠。如果測試按順序運行並按照您提到的方式修改測試,則這非常安全。 – skirsch

回答

12

您必須確保在tearDown方法中調用DateTimeUtils.setCurrentMillisSystem()。所以一個測試不會影響另一個。即使您的測試發生異常,TestNG也應該調用tearDown

我經常更喜歡另一種方式,當我想從System.currentTimeMillis();分離一個類。我介紹一個接口Clock和一個實現SystemClock這樣的:

public interface Clock { 
    public long getCurrentTimeMillis(); 
} 

public class SystemClock implements Clock { 
    public long getCurrentTimeMillis(){ 
     return System.currentTimeMillis(); 
    } 
} 

因爲這是那麼容易創建一個模擬,要麼返回每次調用或一系列預定義的時間固定時間的考驗。

有些人可能會爭辯說,引入這樣一個接口來解耦只有一種方法是過度工程,並且這會影響性能。但幸運的是,我們有一個JIT編譯器,因爲JIT知道只有SystemClock類被加載,所以它知道沒有其他實現存在(此刻)。在這個假設下,它可以使用內聯方法。

所以我更願意以最好的方式編寫代碼。