2016-12-21 4 views
4

Я пытаюсь проверить метод Get в репозитории. Подпись выглядит следующим образом:Moq с точным выражением <Func <TEntity, bool >>

public virtual IEnumerable<TEntity> Get(
     Expression<Func<TEntity, bool>> filter = null, 
     Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, 
     string includeProperties = "") 

Этот метод обычно вызывается следующим образом:

Department targetDepartment = 
      _departmentRepository.Get(department => department.Id == departmentId).FirstOrDefault(); 

Он прекрасно работает с реальными данными, это когда я пытаюсь настроить этот метод, чтобы вернуть конкретный " Департамент "с конкретной лямбдой, где проблемы начинаются.

До сих пор я пытался много способов, чтобы дразнить его, и вот некоторые из них:

1)

Expression<Func<Department, bool>> filterExpression2 = d => d.Id == DepartmentId; 

_departmentRepositoryMock.Setup(repo => repo.Get(
    It.Is<Expression<Func<Department, bool>>>(y => filterExpression2.Compile()(firstDepartment)), 
    null, 
    It.IsAny<string>())) 
         .Returns(new List<Department>() { firstDepartment }.AsQueryable()); 

2)

Expression<Func<Department, bool>> filterExpression2 = d => d.Id == DepartmentId; 

_departmentRepositoryMock.Setup(repo => repo.Get(
    It.IsAny<Expression<Func<Department, bool>>>(), 
    null, 
    It.IsAny<string>())) 
         .Returns(new List<Department>() { firstDepartment }.Where(filterExpression2.Compile()).AsQueryable()); 

Я видел много подобных вопросов, но так или иначе никому из них не помогает.

То, что я пытаюсь сделать, - заставить измененный репозиторий возвращать определенный отдел в зависимости от параметра «Id», отправленного на лямбда.

Я знаю много ответов, используя It.IsAny, но это не то, что я хочу, поскольку это вызовет совпадение буквально любого выражения, переданного в метод Get.

Может ли кто-нибудь помочь мне или хотя бы подтолкнуть меня в правильном направлении?

+0

А также соответствует близко к этому [Moq Возвращает с несколькими Linq выражений] (http://stackoverflow.com/a/35569731/5233410) – Nkosi

ответ

4

Пробовал следующий минимальный пример и смог пройти тест. Обратите внимание на настройку и возврат.

[TestClass] 
public class UnitTest11 { 
    [TestMethod] 
    public void TestMethod1() { 
     //Arrange 
     //fake data 
     var list = Enumerable.Range(1, 10).Select(id => new Department { Id = id }).ToList(); 

     var mock = new Mock<IRepository<Department>>(); 

     mock 
      .Setup(repo => repo.Get(
       It.IsAny<Expression<Func<Department, bool>>>(), 
       null, 
       It.IsAny<string>()) 
      ) 
      .Returns(
       (
        Expression<Func<Department, bool>> filter, 
        Func<IQueryable<Department>, IOrderedQueryable<Department>> orderBy, 
        string includeProperties 
       ) => { 
        var func = filter.Compile(); 
        var result = list.Where(func); 

        if (orderBy != null) { 
         result = orderBy(result.AsQueryable()); 
        } 

        return result; 
       } 
      ); 

     var sut = new MyClass(mock.Object); 

     var departmentId = 2; 

     //Act 
     var actual = sut.GetDepartment(departmentId); 

     //Assert 
     Assert.IsNotNull(actual); 
     Assert.AreEqual(actual, list[departmentId - 1]); 

    } 


    public class MyClass { 
     private readonly IRepository<Department> _departmentRepository; 

     public MyClass(IRepository<Department> repository) { 
      this._departmentRepository = repository; 
     } 

     public Department GetDepartment(int departmentId) { 
      Department targetDepartment = _departmentRepository.Get(department => department.Id == departmentId).FirstOrDefault(); 

      return targetDepartment; 
     } 
    } 

    public class Department { 
     public int Id { get; set; } 
    } 

    public interface IRepository<TEntity> { 
     IEnumerable<TEntity> Get(
      Expression<Func<TEntity, bool>> filter = null, 
      Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, 
      string includeProperties = "" 
     ); 
    } 
} 
+0

Спасибо, но это не совсем то, что я ищу - он по-прежнему использует IsAny. В идеале мне бы хотелось что-то вроде этого: – Shvets

+0

_departmentRepositoryMock.Setup (repo => repo.Get (x => x.Id == DepartmentId, null, String.Empty)) . Возвраты (новый список () {firstDepartment}) ; – Shvets