【问题标题】:Moq with exact Expression<Func<TEntity, bool>>具有精确表达式<Func<TEntity, bool>> 的起订量
【发布时间】:2017-05-07 02:26:21
【问题描述】:

我正在尝试测试存储库的 Get 方法。签名如下:

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();

它适用于真实数据,这是当我尝试设置此方法以返回具有特定 lambda 的特定“部门”时问题开始的地方。

到目前为止,我已经尝试了很多方法来模拟它,下面是其中的一些:

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());

我看到很多类似的问题,但不知何故没有一个有用。

我要做的是强制模拟存储库根据发送到 lambda 的“Id”参数返回特定部门。

我知道许多使用 It.IsAny 的响应,但这不是我想要的,因为它会触发对传递给 Get 方法的任何表达式的匹配。

谁能帮助我,或者至少把我推向正确的方向?

【问题讨论】:

标签: c# linq unit-testing moq


【解决方案1】:

尝试了以下最小示例并且能够通过测试。注意设置和返回。

[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 = ""
        );
    }
}

【讨论】:

  • 谢谢,但这并不是我想要的——它仍然使用 IsAny。理想情况下,我想要这样的东西:
  • _departmentRepositoryMock.Setup(repo => repo.Get(x => x.Id == DepartmentId, null, String.Empty)) .Returns(new List() {firstDepartment}) ;
猜你喜欢
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 1970-01-01
相关资源
最近更新 更多