我有一種方法,根據當前日期是從數據庫中獲取的數據實現不同的邏輯。Java中的單元測試基於時間的邏輯
我想通過讓單元測試創建對象並將它們保存在數據庫中並調用測試方法來測試它。但是,爲了獲得可預測的結果,我需要每次更改系統日期,並且我不知道如何在Java中執行此操作。
對此提出建議?
我有一種方法,根據當前日期是從數據庫中獲取的數據實現不同的邏輯。Java中的單元測試基於時間的邏輯
我想通過讓單元測試創建對象並將它們保存在數據庫中並調用測試方法來測試它。但是,爲了獲得可預測的結果,我需要每次更改系統日期,並且我不知道如何在Java中執行此操作。
對此提出建議?
您可以使用當前日期生成您的預期結果。
或者你編寫你的系統使用測試時的日期/時間(而不是時鐘)這樣的時間總是測試期望的。
我使用類似
interface TimeSource {
long currentTimeMS(); // actually I have currentTimeNS
void currentTimeMS(long currentTimeMS);
}
enum VanillaTimeSource implements TimeSource {
INSTANCE;
@Override
public long currentTimeMS() {
return System.currentTimeMillis();
}
@Override
public void currentTimeMS(long currentTimeMS) {
// ignored
}
}
class FixedTimeSource implements TimeSource {
private long currentTimeMS;
@Override
public long currentTimeMS() {
return currentTimeMS;
}
@Override
public void currentTimeMS(long currentTimeMS) {
this.currentTimeMS = currentTimeMS;
}
}
在測試中,我使用能夠數據例如被驅動FixedTimeSource由輸入/事件設置。在生產中,我使用VanillaTimeSource.INSTANCE,它忽略輸入/事件中的時間並使用當前時間。
第一個建議可能贏了沒有工作。我也應該提到,準確提取的數據也是基於日期(根據某一列)。這意味着即使邏輯沒有什麼不同,我也不得不根據一年中的每一天生成不同的結果。我可能會提出第二個建議 – Alex 2012-02-23 09:32:03
在檢查結果之前,您可以生成預期結果作爲運行測試的一部分。你不需要提前生成它們。 – 2012-02-23 09:34:11
實際上,將接收時間的類/組件作爲參數確保它是一個很好的組件,因爲它可以從系統時間中解耦。您將所有應用程序特定的配置(「使用系統時間」)放在組件外。它只需要依靠外部可配置的刺激。 – helios 2012-02-23 09:46:27
你需要注意在你的課堂上注入一些東西,讓你可以自定義時間的呈現方式。
例如
public interface TimeProvider {
DateTime getCurrentTime();
}
public class UnderTest {
// Inject this in some way (e.g. provide it in the constructor)
private TimeProvider timeProvider;
public void MyMethod() {
if (timeProvider.getCurrentTime() == "1234") {
// Do something
}
}
}
現在在單元測試中,你可以提供假的實施時間提供商。在實際生產代碼中,您可以返回當前日期時間。
當然,你也可以提供它作爲'belgther'建議的參數:) – 2012-02-23 09:20:52
最近我有一個類似的問題,我無法重構代碼太多(時間限制,不想無意間破壞任何東西)。它有一個我想測試的方法,稱爲System.currentTimeMillis(),我想測試的情況取決於返回的值。喜歡的東西:
public class ClassINeedToTest {
public boolean doStuff() {
long l = System.currentTimeMillis();
// do some calculation based on l
// and return the calculation
}
}
爲了讓單元測試,我重構了類,所以它有其保護
protected long getCurrentTimeMillis() {
// only for unit-testing purposes
return System.currentTimeMillis();
}
一個輔助方法,該方法是由doStuff稱爲()。這並沒有改變的功能,但現在的意思是,當我把它的單元測試,然後我可以重寫此方法以返回一個特定的值,例如
ClassINeedToTest testClass = new ClassINeedToTest() {
protected long getCurrentTimeMillis() {
// return specific date for my test
return 12456778L;
}
};
boolean result = testClass.doStuff();
// test result with an assert here
然而,這意味着我已經污染了我的班級的界面,所以你可能會決定成本太高。如果你可以更多地重構代碼,可能會有更好的方法。
改變你的方法,這樣你的確可以把時間作爲參數,那麼你可以通過給你任何你想要的時間來測試它。這又是什麼話? – belgther 2012-02-23 09:19:26
你能告訴你如何得到當前的日期和時間?也許嘲笑會起作用... – 2012-02-23 09:22:15
現在只需用'new Date()',也許我需要一個TimeProvider類 – Alex 2012-02-23 09:43:41