2013-06-21 58 views
5

作爲Java代碼的一部分,某些任務需要在明天在JUnit中完成。在JUnit測試夾具中設置時間和日期

比如有3項任務:

  • TASK1 - 做
  • TASK2 - 明天再做
  • TASK3 - 那麼結果會是

所以按規定,我需要用Java來設定今天的日期。

+0

你能告訴我們你的單元測試的來源嗎? – tbsalling

+0

我不需要使用任何框架。我只需要三個任務就像三個方法calls.f1() - > f2() - > f3()。 f2可以在明天完成,然後在結果f3中被調用。 – hi5

+0

另請參閱http://stackoverflow.com/questions/10652097/simulating-the-passing-of-time-in-unittesting – Raedwald

回答

5

關鍵是要提取「能給你當前時間的東西」的想法作爲依賴。 (與相應的時區一起)。

因此,使用Clock抽象,而不是使用new Date()System.currentTimeMillis()。對於生產代碼,您會注入一個使用底層系統時鐘的實例,但爲了測試您使用了可以明確控制的假時鐘,以使其返回您想要的任何內容。

(這真的不清楚究竟你想達到什麼樣的,是誠實的 - 但這種做法是我的標準的方法來製作時間檢驗的)

9

你的問題的根源是系統時鐘(什麼讓你在new Date()時間)沒有給你你的測試需要的時間。

您可以通過引入間接級別來避免此問題。您不需要直接向Java API詢問當前的時間,就可以讓您的代碼詢問時間是什麼。在真正的程序中,您的Clock實現使用系統時鐘。對於你的單元測試,你使用FakeClock,它表示你想要的時間。你告訴你的代碼使用什麼Clock使用依賴注入。你必須親自編寫接口(或抽象基類)及其具體實現。

這種方法需要你改變你現有的代碼,所以測試起來比較容易,或者先把它寫出來,這樣更容易測試。這是單元測試的技巧之一。

我正在研究一些對時間敏感的代碼。我的時鐘界面很簡單

public interface Clock { 
    long getCurrentTime(); 
} 
3

考慮在GitHub上下面的代碼:DateSupplier & & DateControllerDateSupplier有一個返回當前日期的靜態方法。 DateController允許您操作在測試環境中由DateSupplier返回的日期值。它是一個JUnit Rule,並自行清理。

這是來自其他兩個答案的Clock想法的具體實現。我一直在我的項目中使用它一年左右,取得了很好的成功。任何時候我有代碼將會做new Date()我改爲撥打DateSupplier.getCurrentDate()

2

考慮使用Joda Time,它是Java日期和時間類的替代品。它提供了

DateTimeUtils.setCurrentMillisFixed(long millis); 

它可以在你的測試中使用。

+0

+1。我一直在設置一個有限的試用版,並且繼續看到喬達時間的答案是關於時間的答案。這是值得改變爲喬達時代的問題。我花了不到一個小時的時間來安裝它,更改我的代碼來使用它,並用這個建議來設置我的測試。 –

+0

該調用應該是'DateTimeUtils.setCurrentMillisFixed(...)'。這是設定特定日期時間的要求。 'DateTimeUtils.setCurrentMillisSystem()'(無參數)將DateTime設置爲使用當前系統時間。見http://www.joda.org/joda-time/apidocs/index.html –

相關問題