我已经阅读了很多关于这个话题的其他质量保证,我仍然找不到我的问题的解决方案,所以我决定揭露我的情况.
我有这个界面
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); }
我一直在尝试使用这种方式设置模拟器:
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并不容易,不推荐,但对我来说非常重要,因为“Find”是我在应用程序中使用很多的一种方法
问题是您正在尝试将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中运行该代码时,它通过,所以没有抛出异常)