Dot-Net
Moq.Mock<Expression<Func<T,bool>>>() - 如何使用 Moq 將表達式設置為 Mock
我已經閱讀了很多關於這個主題的其他 QA,但我仍然找不到解決我的問題的方法,所以我決定公開我的案例。
我有這個界面
public interface IRepository<T> where T : class, IEntity { IQueryable<T> Find(Expression<Func<T, bool>> predicate); T FindIncluding(int id, params Expression<Func<T, object>>[] includeProperties); }這是包含我要設置的 Mock 的方法的基本結構
public PeopleController CreatePeopleController() { var mockUnitofWork = new Mock<IUnitOfWork>(); var mockPeopleRepository = new Mock<IRepository<Person>>(); mockPeopleRepository.Setup(r=>r.Find().Returns(new Person(){}); mockUnitofWork.Setup(p => p.People).Returns(mockPeopleRepository.Object); return new PeopleController(mockUnitofWork.Object); }我一直在嘗試使用這種方式設置 Mock:
public PeopleController CreatePeopleController() { var mockUnitofWork = new Mock<IUnitOfWork>(); var mockPeopleRepository = new Mock<IRepository<Person>>(); mockPeopleRepository.Setup(r=>r.Find(It.isAny<Expression<Func<Person,bool>>>()).Single()).Returns(new Person(){}); mockUnitofWork.Setup(p => 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<IRepository<Person>>(); myMock.Setup(r => r.Find(It.IsAny<Expression<Func<Person, bool>>>())).Returns(new List<Person>() { new Person() }.AsQueryable()); Assert.IsTrue(true); }在這裡,您只是使用 setup 對 Find() 方法進行存根,並在 Returns() 子句中執行所有其他操作。我一般會建議這種方法。設置應該準確地反映您的模擬項目,並且您可以為 Returns() (或 Throws() 或其他)呼叫做一堆黑魔法,讓它做你想做的事。
(當我在 VS 中執行該程式碼時,它通過了,所以它沒有拋出異常)