【问题标题】:Mock Dependency Injection repository with filter带有过滤器的模拟依赖注入存储库
【发布时间】:2013-09-03 08:24:16
【问题描述】:
尝试模拟存储库:
var expMock = new Mock<IEntityRepository>();
expMock.Setup(s => s.GetMany(It.IsAny<Expression<Func<Entity, bool>>>()))
.Returns<IQueryable<Entity>>(r =>
new List<Entity>{ new Entity() } }.AsQueryable());
但是当我调用它时:
IEnumerable<Entity> source = _entityRepository.GetMany(w => w.IsActive);
我得到一个例外:
System.ArgumentException : 对象类型
'System.Linq.Expressions.Expression1[System.Func2[Entity,System.Boolean]]'
无法转换为类型“System.Linq.IQueryable`1[Entity]”。
【问题讨论】:
标签:
c#
unit-testing
mocking
moq
【解决方案1】:
只需返回您希望模拟方法返回的值。在您的情况下,它将是 IQueryable:
expMock.Setup(s => s.GetMany(It.IsAny<Expression<Func<Entity, bool>>>()))
.Returns(new List<Entity>{ new Entity() }.AsQueryable());
Returns方法的泛型参数是被调用方法的参数类型。 Returns<IQueryable<Entity>> 表示应该使用 IQueryable<Entity> 类型的参数调用 GetMany 方法,这当然不是真的。这就是你得到这个异常的原因。
方法参数是表达式,因此正确的模拟设置应如下所示:
.Returns<Expression<Func<Entity, bool>>>(e =>
new List<Entity> { new Entity() }.AsQueryable());
但是因此您不需要方法参数来提供返回结果,请使用上面的代码。
【解决方案2】:
您的Returns() 语句绑定了您的Func,以便在调用GetMany() 时返回,而不是评估表达式并返回结果。如果您取出r=>,它应该可以工作。没有类型参数你也可以侥幸逃脱。