如何为动态 linq 设置模拟对象

how to setup mock object for dynamic linq

一项服务正在调用存储库函数 "GetManyIncluded",该函数具有如下所述的签名

     IQueryable<T> GetManyIncluded(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] children);

在测试方法中,我按照下面提到的方式进行设置

            mockedWrapper.Setup(x => x.DomainObject.GetManyIncluded(It.IsAny<Expression<Func<DomainObject, bool>>>(), It.IsAny<Expression<Func<DomainObject, object>>[]>())).Returns<Expression<Func<DomainObject, bool>>>(expr => listOFObjects.Where(expr.Compile()).ToList().AsQueryable());

这让我在服务中出现参数计数不匹配异常。

请帮忙。

重现提问者自己找到的解决方案。

当您使用接受 Func 委托的 Returns 的重载之一时,就会出现问题。 Func 必须 或者 取零参数(即 Func<TResult>,其中 TResult 在编译时已知为 IQueryable<DomainObject> case) or 获取与您设置的方法相匹配的确切参数列表(Func<T1, T2, T3, ..., Tn, TResult> 其中 n T 匹配模拟方法的参数列表)。

您尝试使用模拟方法中的参数子集,但这是不允许的(将无错误地执行 Setup,但在调用该方法时会因参数计数不匹配异常而失败模拟对象)。

因此解决方案是:

  mockedWrapper
    .Setup(x => x.DomainObject.GetManyIncluded(
      It.IsAny<Expression<Func<DomainObject, bool>>>(),
      It.IsAny<Expression<Func<DomainObject, object>>[]>()
      ))
    .Returns(
          (
          Expression<Func<DomainObject, bool>> where,
          Expression<Func<DomainObject, object>>[] children
          )
            => listOFObjects.Where(where.Compile()).ToList().AsQueryable()
      );