asp.net-mvc - 如何使用 Moq 模拟存储库 Single(Expression<Func<TEntity, bool>> predicate) 方法

标签 asp.net-mvc moq

我目前正在使用 .NET MVC 并编写一些单元测试。我有一个如下所示的接口(interface)存储库:

public interface IRepository<TEntity> : IDisposable where TEntity : class
{
    IQueryable<TEntity> GetAll();
    TEntity Single(Expression<Func<TEntity, bool>> predicate);
}

我已经像这样 mock GetAll 方法:
 _mockRepository.Setup(x => x.GetAll()).Returns(
            new List<Post>
                {
                    new Post { Title = "Test Post 1" }, 
                    new Post { Title = "Test Post 2" }
                }.AsQueryable());

现在我不确定如何模拟 Single 方法,因为它有一个包含我要评估的表达式的参数。

谢谢,

b3n

编辑:

我将代码更改为:
_mockRepository.Setup(x => x.Single(It.IsAny<Expression<Func<Post, bool>>>()))
       .Returns( (Expression<Func<Post, bool>> expr) => new List<Post> { 
        new Post { PostId = 1, Title = "Test Post 1", Created = DateTime.Now }, 
        new Post { PostId = 2, Title = "Test Post 2", Created = DateTime.Now }    
        }.Where(expr));

但我现在收到以下错误:

'System.Collections.Generic.List' 不包含 'Where' 的定义,并且最佳扩展方法重载 'System.Linq.Queryable.Where(System.Linq.IQueryable, System.Linq.Expressions.Expression>)' 具有一些无效的论点。

这甚至是最好的方法还是应该只返回一个新的 Post 而不考虑传入的表达式?

编辑2:

这是工作结果。
_mockRepository.Setup(x => x.Single(It.IsAny<Expression<Func<Post, bool>>>())).Returns(
            (Expression<Func<Post, bool>> expr) =>
            new List<Post>
                {
                    new Post { PostId = 1, Title = "Test Post 1", Created = DateTime.Now },
                    new Post { PostId = 2, Title = "Test Post 2", Created = DateTime.Now }
                }.Single(expr.Compile()));

最佳答案

如果您需要使用参数,我相信您可以在 Returns 方法中使用参数匹配器和 lambda:

_mockRepository.Setup(x => x.Single(It.IsAny<Expression<Func<TEntity, bool>>>())
               .Returns((Expression<Func<TEntity, bool>> expr) => ... );

编辑:
您现在遇到的错误是因为您试图将表达式树传递给 LINQ-To-Objects 的 Where 方法。要解决此问题,请使用以下命令:
_mockRepository.Setup(x => x.Single(It.IsAny<Expression<Func<Post, bool>>>()))
   .Returns( (Expression<Func<Post, bool>> expr) => new List<Post> { 
    new Post { PostId = 1, Title = "Test Post 1", Created = DateTime.Now }, 
    new Post { PostId = 2, Title = "Test Post 2", Created = DateTime.Now }    
    }.Where(expr.Compile()));

Compile() 将表达式树转换为简单的 Func 委托(delegate)。此外,由于模拟方法返回单个对象,因此 Where() 也不起作用。

关于asp.net-mvc - 如何使用 Moq 模拟存储库 Single(Expression<Func<TEntity, bool>> predicate) 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4976651/

相关文章:

c# - 如何在 Startup.cs 文件中获取 ASP.NET MVC 应用程序的基本 url?

c# - Moq 定义严格的模拟

c# - 如何模拟执行复杂 Entity Framework LINQ 查询的对象?

c# - 在 C# 中使用 Moq 测试回调

c# - 在运行时动态调用 Moq Setup()

c# - 如何从操作的 MethodInfo 中获取 MVC 操作信息?

asp.net-mvc - asp.net mvc 3 中 DataAnnotations 的行为是否发生了变化?

asp.net-mvc - 允许匿名用户访问受组织帐户身份验证保护的网站的某些区域

c# - 带有 Action /函数参数的接口(interface)的最小起订量设置

asp.net-mvc - MVC 中的 SSRS Reportviewer,通过自动调整 iframe 大小以适合报表来删除 iframe 滚动条