Как использовать Moq для макета репозитория Single (выражение <Func <TEntity, bool >> предикат) метод - PullRequest
4 голосов
/ 12 февраля 2011

Я сейчас играю с .NET MVC и пишу несколько юнит-тестов. У меня есть хранилище интерфейса, которое выглядит так:

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

Я издевался над методом 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

Edit:

Я изменил код на:

_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' не содержит определения 'Где' и наилучшей перегрузки метода расширения 'System.Linq.Queryable.Where (System.Linq.IQueryable, System.Linq.Expressions.Expression> ) 'имеет недопустимые аргументы.

Является ли это даже лучшим подходом для этого или единственный метод должен возвращать только новое сообщение, даже не учитывая переданное выражение?

Редактировать 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()));

1 Ответ

4 голосов
/ 12 февраля 2011

Я считаю, что вы можете использовать сопоставление аргументов, а также лямбду в методе Returns, если вам нужно использовать аргумент:

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

Edit: Ошибка, которую вы сейчас получаете, заключается в том, что вы пытаетесь передать дерево выражений методу Where LINQ-To-Objects. Чтобы исправить это, используйте следующее:

_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. Кроме того, поскольку mocked-метод возвращает один объект, Where () также не будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...