2011-09-15 68 views
1

我有以下的方法,我想單元測試:單元測試時間差

public void Upload(string identifier, Stream data) 
{ 
    var startTime = SystemTime.Now; 

    innerDataIntegrationInterface.Upload(identifier, data); 

    var endTime = SystemTime.Now; 

    TimeSpan totalUploadTime = endTime.Subtract(startTime); 
    float transferRate = data.Length/(float)(totalUploadTime.Seconds + totalUploadTime.Milliseconds); 

    m_log.Info(string.Format("Total uploading time for '{0}' was {1:00}.{2:000000} milliseconds transfered at {3} bytes/sec", identifier, totalUploadTime.Seconds, totalUploadTime.Milliseconds, transferRate)); 
} 

基本上我已經注射SYSTEMTIME對象,所以我可以把它架在我的測試,但我不能弄清楚爲了讓startTime和endTime變量得到不同的值,我可以斷言m_log.Info方法被調用了totalUploadTime和transferRate變量的正確值。

任何想法,將不勝感激。

回答

1

你可以讓你的模擬SystemTime對象增加它在Now Getter中的值嗎?這會讓他們不同。

1

解決這個問題的一種方法是將代碼中的複雜部分(您真正想要測試的部分)提取到另一個類或方法中並對其進行測試。

在這種情況下,這將涉及提取邏輯來計算傳輸速率到一個單獨的方法,該方法需要兩個時間參數和傳輸量。

(又名「收集,然後用」從Mock-Eliminating Patterns。)

4

時鐘的想法 - 這是可以獲取當前時間 - 實際上是一個服務你根據。如果你依靠它明確通過一些接口(IClock)像你會任何其他服務。然後,您可以創建一個「生產」實現,該實現代表System.DateTime.UtcNowSystem.DateTime.Now以及虛假實現或模擬測試。

以我個人的經驗來說,假設你可以設置,推進等等,而不是使用模擬框架來處理這個特定的場景 - 這是我見過並且使用了很多的技巧(這就是爲什麼野田時間用IClock接口和StubClock實現來支持它)。

+0

謝謝喬恩C#中,這是一個偉大的建議,我我一定會使用它。 –

1

如果innerDataIntegrationInterface.Upload是嘲笑界面的一部分,你可以嘲笑Upload方法,如:

var mock = new Mock<innerDataIntegrationInterface>(); 
mock.Setup(m => m.Upload(identifier, data)).Callback<object>(
    c => 
     { 
      //increment SystemTime.Now 
      //or call 
      //Thread.Sleep(1); to sleep for microsecond 
     }); 

以上是使用起訂量