簡體   English   中英

使用moq驗證對具有param參數的函數的調用

[英]Using moq to verify a call to a function with param parameters

我有一個帶LogTrace的ILogger接口(字符串值,params object []參數)。 現在我想驗證是否調用了LogTrace並且要記錄的字符串包含一些id。 問題是它可以被不同地調用。 例如1)LogTrace(“MyString”+ id)2)LogTrace(“MyString {0}”,id)等等。

有沒有一種方法可以讓Moq驗證所有場景? 我只能想到創建一個手工制作的模擬器,它將格式化可用於驗證的字符串。

mock.Verify( m => m.LogTrace( It.IsAny<string>(), It.IsAny<object[]>() ) );

params object[]傳遞給方法object[]反正所以你只需要在陣列某種方式匹配(如上例如,此接受任何東西)。

如果您需要對列表進行更多控制,請使用It.Is匹配器,它允許您創建自己的謂詞:

 mock.Verify( m => m.LogTrace( It.IsAny<string>(),
            It.Is<object[]>(ps =>
                ps != null &&
                ps.Length == 1 &&
                ps[0] is int &&
                (int)ps[0] == 5
            ) ) );

此示例顯示如何驗證param列表是否為空並且包含5作為int類型的唯一參數。

您可以嘗試使用Callback ,但它會變得相當復雜(未經過測試):

var mock = new Mock<ILogger>();
string trace = null;
mock.Setup(l => l.LogTrace(It.IsAny<string>(), It.IsAny<object[]>()))
        .Callback((s1, par) =>
            {
                trace = string.Format(s1, par);
            });

//rest of the test

Assert.AreEqual(expected, trace);

如果ILogger具有一個小接口,您可以考慮手動實現存根(這將保留它應該記錄的所有行),並在測試結束時驗證。 如果您記錄了多行,那么這將是一個更易讀的設置。

我認為在這里做你需要的東西並不簡單。 問題是您需要確保將某個值組合傳遞給您的方法,這會導致許多不同的可驗證方案:

  • 字符串包含ID AND參數包含ID - pass
  • 字符串包含ID AND參數不包含ID - pass
  • String不包含ID AND參數包含ID = pass
  • String不包含ID AND參數不包含ID - 失敗

但是,Moq不支持您的可驗證方法的不同參數之間的這種條件表達式。 一種可能的解決方案是檢查是否缺少 id,而不是在任一參數中存在 嘗試類似的東西:

mock.Verify(m => m.LogTrace(
    It.Is<string>(s => !s.Contains(id)), 
    It.Is<object[]>(o => !o.Contains(id))), Times.Never());

我們在這里做的是驗證是否滿足失敗條件 - 也就是說,你的字符串不包含id,你的對象數組也沒有。 我們使用Times.Never()來確保永遠不會發生這種情況。

但請記住,乍一看代碼可能並不明顯; 一旦你寫完就確保你正確解釋你的意圖。

暫無
暫無

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

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