[英]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
具有一個小接口,您可以考慮手動實現存根(這將保留它應該記錄的所有行),並在測試結束時驗證。 如果您記錄了多行,那么這將是一個更易讀的設置。
我認為在這里做你需要的東西並不簡單。 問題是您需要確保將某個值組合傳遞給您的方法,這會導致許多不同的可驗證方案:
但是,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.