2016-09-20 8 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

は、ウォール時間を表す明示的なパラメータを使用しない

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

そして、あなたのテストでください。テスト中は、このウォールタイムを早送りすることができます。 package net/http/cookiejarがどのように機能するかを見てみましょう。 – Volker

+0

このアプローチでは、機能自体を変更する必要がありますが、これはやる気には消極的です。また、もし私がコードを持っていない関数を含むものをテストしようとしていたら、私は無力だろう。 –

+0

これらのオブジェクトは常に時間を表す明示的なパラメータを持つべきかもしれない。最後にそれを行うかもしれませんが、私は最終的な手段としてそれを考慮しています –

答えて

3

これはAndrew GerrandのTesting Techniques talkで実際に回答されました。あなたのコードでは

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

関連する問題