具有过滤器的模拟依赖注入存储库

时间:2013-09-03 08:24:16

标签: c# unit-testing mocking moq

尝试模拟存储库:

 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.Expression 1[System.Func 2 [实体,System.Boolean]]'   无法转换为'System.Linq.IQueryable`1 [Entity]'。

2 个答案:

答案 0 :(得分:3)

只需返回您希望模拟方法返回的值。在您的情况下,它将是 IQueryable

expMock.Setup(s => s.GetMany(It.IsAny<Expression<Func<Entity, bool>>>()))
       .Returns(new List<Entity>{ new Entity() }.AsQueryable());

返回方法的通用参数是一种被调用方法的参数。 Returns<IQueryable<Entity>>表示应使用GetMany类型的参数调用IQueryable<Entity>方法,当然这不是正确的。这就是你得到这个例外的原因。

Method参数是表达式,因此正确的模拟设置应如下所示:

.Returns<Expression<Func<Entity, bool>>>(e => 
      new List<Entity> { new Entity() }.AsQueryable());

但是因此您不需要方法参数来提供返回的结果,请使用上面的代码。

答案 1 :(得分:1)

您的Returns()语句绑定了在调用Func时返回的GetMany(),而不是评估表达式并返回结果。如果你拿出r=>,它应该有效。你也可以在没有类型参数的情况下离开。