簡體   English   中英

Moq設置將所有空的枚舉/數組視為相同的參數

[英]Moq setup treats all empty enumerables/arrays as the same parameter

我有一個接受IEnumerable的方法:

MyMethod(IEnumerable<MyClass> myParameter)

現在我正在編寫此代碼來模擬服務:

var array1 = new MyClass[0];
var array2 = new MyClass[0];

_service
   .Setup(s => s.MyMethod(array1))
   .Returns(value1);

_service
   .Setup(s => s.MyMethod(array2))
   .Returns(value2);

最后,我正在對服務進行兩次調用,兩個數組都在被測系統中:

_service.MyMethod(array1);
_service.MyMethod(array2);

我所期望的是從這些調用中獲取value1value2 ,但實際上后者調用會覆蓋第一個調用,而我只從兩個調用中獲得value2

這是Moq中的一個錯誤還是這個功能設置將IEnumerable視為一個單獨的對象而是嘗試擴展它並比較所有元素或某些東西(導致兩個空數組是相同的設置調用)?

當您使用Moq在方法上創建多個設置時,除非設置是有條件的(它們在參數上指定了某些條件),否則每個后續設置都將替換先前的設置。 看到這個答案

您可以通過指定參數必須與您要傳遞的參數匹配來修復代碼:

[Test]
public void MyTest()
{
    var service = new Mock<MyClass>();
    var array1 = new MyClass[0];
    var array2 = new MyClass[0];

    var value1 = "value1";
    var value2 = "value2";

    service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array1))).Returns(value1);          
    service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array2))).Returns(value2);

    Assert.AreEqual(value1, service.Object.MyMethod(array1));
    Assert.AreEqual(value2, service.Object.MyMethod(array2));
}

您描述的行為是moq的默認行為,您可以在此處看到它。 它確實展開了可枚舉並調用IEnumerable.SequenceEqual 但是,這是默認行為(如果使用實例設置, Constant匹配器),您可以覆蓋它。 一種方法是歐文建議使用It.Is<T>匹配器,例如

service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array1)))
service.Setup(s => s.MyMethod(It.Is<IEnumerable<MyClass>>(e => e == array2)))

請注意, ==默認情況下執行ReferenceEquals() ,這樣就可以進行不同的不可覆蓋設置。

暫無
暫無

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

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