Dot-Net

Moq.Mock<Expression<Func<T,bool>>>() - 如何使用 Moq 將表達式設置為 Mock

  • April 24, 2013

我已經閱讀了很多關於這個主題的其他 QA,但我仍然找不到解決我的問題的方法,所以我決定公開我的案例。

我有這個界面

public interface IRepository&lt;T&gt; where T : class, IEntity 
{
   IQueryable&lt;T&gt; Find(Expression&lt;Func&lt;T, bool&gt;&gt; predicate);
   T FindIncluding(int id, params Expression&lt;Func&lt;T, object&gt;&gt;[] includeProperties);
}

這是包含我要設置的 Mock 的方法的基本結構

public PeopleController CreatePeopleController()
{
   var mockUnitofWork = new Mock&lt;IUnitOfWork&gt;();
   var mockPeopleRepository = new Mock&lt;IRepository&lt;Person&gt;&gt;();

   mockPeopleRepository.Setup(r=&gt;r.Find().Returns(new Person(){});
   mockUnitofWork.Setup(p =&gt; p.People).Returns(mockPeopleRepository.Object);
   return new PeopleController(mockUnitofWork.Object);
}

我一直在嘗試使用這種方式設置 Mock:

public PeopleController CreatePeopleController()
{
   var mockUnitofWork = new Mock&lt;IUnitOfWork&gt;();
   var mockPeopleRepository = new Mock&lt;IRepository&lt;Person&gt;&gt;();

   mockPeopleRepository.Setup(r=&gt;r.Find(It.isAny&lt;Expression&lt;Func&lt;Person,bool&gt;&gt;&gt;()).Single()).Returns(new Person(){});
   mockUnitofWork.Setup(p =&gt; p.People).Returns(mockPeopleRepository.Object);
   return new PeopleController(mockUnitofWork.Object);
}

但是系統總是拋出相同的異常“System.NotSupportedException:表達式引用了不屬於模擬對象的方法……”

另外我想補充一點,我正在使用 MSTest 和 Moq

我知道使用 Expression 設置 Mock 並不容易且不推薦,但這對我來說非常重要,因為“查找”是我在應用程序中經常使用的一種方法

問題是您試圖將 Single() 擴展方法設置為模擬的一部分。設置呼叫需要有你的方法的結果——而不是你的方法的結果,隨後應用了一些擴展方法。我會試試這個:

   [TestMethod]
   public void MyTestMethod()
   {
       var myMock = new Mock&lt;IRepository&lt;Person&gt;&gt;();
       myMock.Setup(r =&gt; r.Find(It.IsAny&lt;Expression&lt;Func&lt;Person, bool&gt;&gt;&gt;())).Returns(new List&lt;Person&gt;() { new Person() }.AsQueryable());

       Assert.IsTrue(true);
   }

在這裡,您只是使用 setup 對 Find() 方法進行存根,並在 Returns() 子句中執行所有其他操作。我一般會建議這種方法。設置應該準確地反映您的模擬項目,並且您可以為 Returns() (或 Throws() 或其他)呼叫做一堆黑魔法,讓它做你想做的事。

(當我在 VS 中執行該程式碼時,它通過了,所以它沒有拋出異常)

引用自:https://stackoverflow.com/questions/7982465