[英]Are there cases where It.IsAny does not match a value?
我使用 Moq 庫在我的 MVVM WPF 項目中模擬 Prism 庫提供的接口,以便將它們作為我的視圖模型的一部分進行單元測試。 具體來說,我有一個使用IDialogService
的視圖模型。
我想對執行特定命令是否會打開帶有特定參數的特定對話框進行單元測試。 這是我所做的:
// Arrange
var mockDialogService = new Mock<IDialogService>();
var viewModel = SetupViewModel(mockDialogService.Object);
// Act
viewModel.OpenNewStockDialogueCommand.Execute();
// Assert
mockDialogService.Verify(s => s.ShowDialog(
It.IsAny<string>(),
It.IsAny<IDialogParameters>(),
It.IsAny<Action<IDialogResult>>()),
Times.Once);
相關部分發生在我的測試的 Assert 部分。 ShowDialog
方法采用以下 arguments:
string
IDialogParameters
Action<IDialogResult>
這里有一些關於 Prism Dialogservice 的文檔,供有興趣的人參考
現在,據我了解,如果我調用ShowDialog
方法,在調用Verify
方法之前,無論我實際傳遞了哪些參數, Verify
方法都應該毫無例外地完成。 正如您可能在我在論壇上猜到的那樣,它實際上確實引發了異常並向我顯示以下消息:
Message:
Moq.MockException :
Expected invocation on the mock once, but was 0 times: s => s.ShowDialog(It.IsAny<string>(), It.IsAny<DialogParameters>(), It.IsAny<Action<IDialogResult>>())
Performed invocations:
Mock<IDialogService:1> (s):
IDialogService.Show("NewStockDialogue", ?CurrentStock=FHAA.Stock, Action<IDialogResult>)
所以你有 go。 這對我來說很奇怪。 正如“Performed Invocation”所示,該方法似乎確實被調用了,但參數的某些內容不匹配。 有人知道為什么嗎?
同樣重要的是要注意,我實際上並不想把It.IsAny
放在這里,我實際上有一些我想測試的半固定值,但由於它不能與It.IsAny
工作,我有什么希望讓它在限制下工作。
非常感謝您的寶貴時間,非常感謝您的幫助!
編輯
原來我實際上是在測試IDialogService.Show
而不是ShowDialog
。 這是問題
dialogService.Show(DialogueNames.NewStock, parameters, OnNewStockDialogueClosed);
正如@Nkosi 已經指出的那樣,您正在調用Show
方法,但要驗證是否調用了ShowDialog
。 錯誤消息中明確說明了這一點。 決定要使用哪一個並調整測試或查看 model。
同樣重要的是要注意,我實際上並不想把 It.IsAny 放在這里,我實際上有一些半固定值我想測試 [...]
您可以使用It.Is<T>
來檢查參數的條件,而不是使用It.IsAny<T>
。 你只需要傳遞一個Expression<Func<T, bool>>
,它是一個謂詞的表達式。 該謂詞檢查相應參數的正確性並將結果返回為bool
。 看看這個例子。
viewModel.ShowDialog("My dialog name", new DialogParameters {{"Key 1", "Value 1"}}, result => testInt = 32);
我在視圖 model 中調用了這個ShowDialog
。 我可以驗證參數是否正確。
var expectedDialogParameters = new DialogParameters {{ "Key 1", "Value 1" }};
mockDialogService.Verify(s => s.ShowDialog(
It.Is<string>(name => name == "My dialog name"),
It.Is<DialogParameters>(dialogParameters => dialogParameters.SequenceEqual(expectedDialogParameters)),
It.IsAny<Action<IDialogResult>>()),
Times.Once);
對於對話框的名稱,我只檢查 lambda 中的string
是否相等。 對於對話參數,我使用我預期的對話參數的一個實例。 我將DialogParameters
與SequenceEqual
進行比較,因為它們實現為IEnumerable<KeyValuePair<string, object>>
,因此是鍵值對列表。 我不能使用Equals
,因為它沒有在DialogParameters
中被覆蓋,並且只會檢查引用的相等性,這會失敗。 此外,在It.Is
DialogParameters
IDialogParameters
只是DialogParameters
的一個接口,它沒有實現IEnumerable<KeyValuePair<string, object>>
,因此您無法與SequenceEqual
進行比較。 最后但同樣重要的是,您可以驗證對話結果操作,但這可能並不容易。 您可以改為檢查您的視圖 model,由於正在執行的操作而發生了變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.