【问题标题】:Moq Setup for method with expression<Func<t,bool>> argument带有表达式<Func<t,bool>> 参数的方法的起订量设置
【发布时间】:2018-02-23 13:06:05
【问题描述】:

我正在尝试模拟以下存储库方法

IEnumerable<T> All(Expression<Func<T, bool>> criteria)

下面的模拟设置工作正常

repository.Setup(repo => repo.All(It.IsAny<Expression<Func<UserLog, bool>>>())).Returns(userLogs);

但是,当我想使用特定表达式进行设置时,它不起作用。调用时,方法“All”不会返回指定的用户日志对象。

repository.Setup(repo => repo.All(v=>v.UserId==userId)).Returns(userLogs);

我还尝试了以下方法。我知道它很丑,但我很好奇它是否会起作用,而且确实有效。

repository.Setup(ulr => 
                        ulr.All(It.Is<Expression<Func<UserLog, bool>>>(e => 
                        e.Compile().Invoke(new UserLog { UserId = userId }))))
.Returns(userLogs);

然而,奇怪的是,将那个繁琐的表达式移到一个单独的变量中并将其传递进去,并没有奏效。如下所示

var itis = It.Is<Expression<Func<UserLog, bool>>>(e => e.Compile().Invoke(new UserLog { UserId = userId }));
repository.Setup(ulr => ulr.All(itis)).Returns(userLogs);

被模拟的方法被调用如下;

repository.All(u=>u.UserId==userId);

我想做的是模拟特定表达式的方法>。

我不知道这个,希望得到一些帮助。

谢谢。

【问题讨论】:

  • it does not work,这是什么意思?它有任何错误吗?您看到了什么意外行为?
  • 那么设置不起作用。返回函数未按预期调用
  • 您能否添加一个示例,说明对模拟方法的 调用 是什么样的?
  • repository.All(u=>u.UserId==userId);这就是调用模拟方法的方式

标签: c# unit-testing moq


【解决方案1】:

从 mock 中检索传递的表达式并使用 linq 将其应用于假结果

repository
.Setup(_ => _.All(It.IsAny<Expression<Func<UserLog, bool>>>()))
.Returns((Expression<Func<UserLog, bool>> arg) => userLogs.Where(arg.Compile()));

当被模拟的成员被这样的调用时,例如

var repo = repository.Object;
var result = repo.All(user => user.UserId == userId);

假设userLogs 的类型为IEnumerable&lt;UserLog&gt;,将在模拟设置中调用传递给repo 的user =&gt; user.UserId == userId 表达式

【讨论】:

  • 这并不适用于我的情况。 UserLog 集合是通过 AutoFixture 创建的并调用 .Where 不会产生预期的结果。我可以修改我的测试方法以适应这种情况,但如果有更简单的解决方案,我宁愿不这样做。我觉得使用表达式 (u)=>u.UserId == userId) 设置方法应该可以工作。我解释的第二种情况更奇怪。
  • @Rudithus 那么您能否更新原始帖子,以便知道所有必要的详细信息以便能够重现该问题。原帖中没有提到使用固定装置。
  • 我不认为它真的相关,因为我的问题是关于设置模拟方法。我正在寻找的是一种为特定表达式语句设置方法调用的方法。
猜你喜欢
  • 1970-01-01
  • 2016-09-22
  • 1970-01-01
  • 2017-05-07
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
相关资源
最近更新 更多