簡體   English   中英

如何對以下場景進行單元測試?

[英]How to unit test the following scenario?

我有以下方法

    public override void SendSync(int frame, byte[] syncData)
    {
        using (var ms = new MemoryStream(4 + syncData.Length))
        {
            ms.WriteArray(BitConverter.GetBytes(frame));
            ms.WriteArray(syncData);

            queuedSyncPackets.Add(ms.GetBuffer());
        }
    }

我想對其進行單元測試以保證兩件事:

  1. ms設置在最后 ok 將使用 roslyn
  2. 4 + syncData.Length等於ms.GetBuffer().Capacity就在queuedSyncPackets.Add(ms.GetBuffer());

我怎樣才能做到這一點?

哲學部分:

你真的不應該單元測試方法是如何在內部實現的。 您應該測試它的行為是否正確,但不應要求特定的實現。 在這種情況下,僅使用新數組和兩個復制操作而不是使用 MemoryStream 來實現方法會更清楚 - 要求該方法創建和處置內存流或使用特定字節數組可能是錯誤的。 事實上,如果您希望使用某些特定的緩存/池,您可以斷言。

ms 放在最后:

測試using MemoryStream使用情況的存在 - 由於MemoryStream沒有非托管組件,所以如果您有一個或沒有顯示代碼,絕對不會發生任何變化( Dispose將阻止將來可能影響其他使用模式的讀/寫操作)。 因此,這種特殊情況幾乎是風格偏好,應該由代碼分析器或代碼審查捕獲。

如果您真的想測試它 - 一種選擇是將流的創建移動到工廠方法並捕獲創建的流以供以后驗證。 就像是

 public override void SendSync(
       int frame, byte[] syncData, Func<MemoryStream> streamFactory)
 {
       using (var ms = streamFactory())...
 }

 ...MyTest()
 {
    var ms = new MemoryStream();
    SendSync(..., ()=>ms);
    Assert.IsFalse(ms.CanRead, 
       "Expecting stream to be disposed and hence no more readable");
 }

注意:正如評論和問題中提到的那樣,對於這種特殊情況,測試該流是否已被處理可能有點過頭了。 如果有人將其刪除為不必要的,而其他人將其添加為“我們的編碼標准要求”,則無法通過單元測試解決 - 而是與人交談。

檢查方法的參數:

假設queuedSyncPackets是一個注入的依賴項,您只需要在調用預期數據時添加檢查。 通常使用一些模擬框架(如moq ,但您可以實現自己的類,該類只需檢查該調用中的數組大小。

請注意,帖子中顯示的代碼將通過檢查,但並非必須(因為該部分行為未記錄)。 GetBuffer()返回 MemoryStream 的內部數組,其大小等於或大於結果數據,但不能保證在沒有剩余空間時不會增長流。 如果您必須使用GetBuffer() ,您也必須傳遞流的大小。

使用 moq 進行測試的近似樣本:

byte[] theBuffer = null;
mockQueuedSyncPackets.Setup(c => c.Add(It.IsAny<byte[]>()))
        .Callback<byte[]>((obj) => theBuffer = obj);
var theSender = new Sender(mockQueuedSyncPackets.Object);
theSender.SendSync(123, syncData);
Assert.AreEqual(4 + syncData.Length, theBuffer.Length);         

暫無
暫無

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

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