簡體   English   中英

是否存在 It.IsAny 不匹配值的情況?

[英]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:

  1. 名稱: string
  2. 參數: IDialogParameters
  3. 回調: 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是否相等。 對於對話參數,我使用我預期的對話參數的一個實例。 我將DialogParametersSequenceEqual進行比較,因為它們實現為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.

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