2016-09-20 113 views
2

有一個對象依賴於計時來正確運行。不幸的是,定時持續時間本身太長,不能實時對其進行實時測試,縮短持續時間會因測試對象的性質而影響測試的目的。涉及時間的Golang測試程序

測試此類對象的最佳方法是什麼?理想情況下,會有一些虛擬時鐘可以任意快速運行,可以使用。

type Obj struct{} 
func (o Obj) TimeCriticalFunc(d time.Duration) bool { 
    //do stuff 
    //possibly calling multiple times time.Now() or other real time related functions 
} 

func TestTimeCriticalFunc(t *testing.T) { 
    if !Obj{}.TimeCriticalFunc(10 * 24 * time.Hour) { 
     t.Fail() 
    } 
} 
+0

使用代表掛鐘時間明顯的參數。在測試過程中,您可以快速前進這段時間。看看package net/http/cookiejar是如何做到的。 – Volker

+0

這種方法需要修改函數本身,但我不太願意這樣做。還帶來了一個問題,如果我要測試一些涉及我沒有代碼的函數的東西,我會很無奈 –

+0

也許這些類型的對象應該總是有一個顯式的參數來表示時間。最後可能會這樣做,但我確實認爲這是最後的手段 –

回答

3

這實際上是在Andrew Gerrand的Testing Techniques talk中回答的。在你的代碼做

var (
    timeNow = time.Now 
    timeAfter = time.After 
) 

// ... 

type Obj struct{} 
func (o Obj) TimeCriticalFunc(d time.Duration) bool { 
    // Call timeAfter and timeNow. 
} 

而且在測試中做

func TestTimeCriticalFunc(t *testing.T) { 
    timeNow = func() time.Time { 
     return myTime // Some time that you need 
    } 
    // "Redefine" timeAfter etc. 
    if !Obj{}.TimeCriticalFunc(10 * 24 * time.Hour) { 
     t.Fail() 
    } 
} 
+1

還值得注意的是,測試函數設置爲'timeNow'變量(函數時間)的匿名函數/閉包可以跟蹤它的次數調用,它可能會根據調用返回不同的值。例如。 'timeNow'可能會先返回'00:00',下次通話時可能會返回'00:01'等。請參閱[Go Playground]上的示例(https://play.golang.org/p/Ac7PcaTJ_Z)。 – icza