簡體   English   中英

如何對心跳模式進行單元測試?

[英]How to unit test the heartbeat pattern?

我正在編寫一個客戶端,每秒向服務器發送一個“心跳信號”。 客戶端在后台線程中調用WCF服務以報告其活動。

如何對此進行單元測試? 我是否需要等待幾秒鍾並檢查是否多次調用了適當的方法?

它應該是某種情景測試嗎? 也許我不應該擔心在整個客戶的整個生命周期中不斷調用服務?

我可以測試對WCF服務的單個調用,但它不測試“心跳模式”。

我正在使用TDD方法。 (C#,NUnit,Moq)

有什么建議或例子嗎?

編輯:

我認為還不夠清楚。

這是我所擁有的更簡單的版本:

public class FeedService
{
   private Timer t;

   public FeedService()
   {
      t.Interval = 1000;
      t.Elapsed += TimerElapsed;
      t.Start();
   }

   private void TimerElapsed(object sender, ElapsedEventArgs e)
   {
      t.Stop();
      SendHeartbeat();
      t.Start();
   }
}

......這是我的考驗:

[Test]
public void Heartbeat_called_twice_after_2_seconds()
{
  var mockFeedService = new Mock<FeedService>();

  Thread.Sleep(2000);
  mockFeedService.Verify(x => x.SendHeartBeat(), Times.AtLeast(2));
}

我有兩個問題:
1)為什么我的測試總是失敗? 我做錯了什么?
2)我應該測試一下嗎?

必須首先隔離要測試的功能。 例如,在這種情況下,可以測試兩個方面。 一個是listenbeat組件實際上在指定的時間表上發送心跳消息。 另一個是服務接收消息。 如果您抽象服務,那么您可以獨立於服務實現測試聽力組件。 這可以在單元測試中通過啟動聽力組件然后休眠,然后驗證存根或模擬服務實現接收到預期數量的消息來完成。 確保服務正在接收消息的測試集成測試 ,因此不是“純”單元測試。 但是,由於必須進行測試,因此您也可以使用測試用例。

我將在“網關”類型類中包裝與服務的交互。 這可以在測試中由模擬替換,模擬可以計算您所做的調用,或者您可能需要的任何統計信息。

此致,莫滕

嚴格來說,您要測試的方案集成測試。

我采用的類似測試構建方案的方法是使用這個方便的功能:

/// <summary>
/// Wait no longer than @waitNoLongerThanMillis for @thatWhatWeAreWaitingFor to return true.
/// Tests every second for the 
/// </summary>
/// <param name="thatWhatWeAreWaitingFor">Function that when evaluated returns true if the state we are waiting for has been reached.</param>
/// <param name="waitNoLongerThanMillis">Max time to wait in milliseconds</param>
/// <param name="checkEveryMillis">How often to check for @thatWhatWeAreWaitingFor</param>
/// <returns></returns>
private bool WaitFor(Func<bool> thatWhatWeAreWaitingFor, int checkEveryMillis, int waitNoLongerThanMillis)
{
    var waitedFor = 0;
    while (waitedFor < waitNoLongerThanMillis)
    {
        if (thatWhatWeAreWaitingFor()) return true;

        Console.WriteLine("Waiting another {0}ms for a situation to occur.  Giving up in {1}ms ...", checkEveryMillis, (waitNoLongerThanMillis - waitedFor));
        Thread.Sleep(checkEveryMillis);
        waitedFor += checkEveryMillis;
    }
    return false;
}

用法:

// WaitFor (transaction to become failed, checkEverySoOften, waitNoLongerThan)
int wait = (Settings.EventHandlerCoordinatorNoActivitySleepTime + 5) * 1000;
var failedEventExists = WaitFor(() => EventQueueManager.GetFailedEvents(0, 10).TotalRecords > 0, checkEveryMillis: 1000, waitNoLongerThanMillis: wait);

if (!failedEventExists)
    Assert.Fail("Waited longer than " + wait + " without any evidence of the event having been handled.  Expected to failed event on the queue.");

它使用自.Net4以來僅提供的c#功能,但這可能適合大多數.Net開發人員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM