[英]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);
我所期望的是從這些調用中獲取value1
和value2
,但實際上后者調用會覆蓋第一個調用,而我只從兩個調用中獲得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.