你可以将'It'匹配器对象存储为变量,而不是将其定义为内联吗?(MOQ)

Mic*_*eld 9 .net c# moq mocking

我正在使用Moq模拟一些对象,其中一些可能有相当冗长的参数集合请求对象作为参数传入.

为了便于重复使用和样式,我希望能够使用特定参数存储这些请求,以便在模拟设置中使用.例如:

mockedObject
  .Setup(mo =>
    mo.GetBobbins(It.Is<GetBobbinsRequest>
      (r.Parameter1 == value1 && [...] & r.ParameterN == valueN))
  .Returns(someBobbins);
Run Code Online (Sandbox Code Playgroud)

变为:

var request = It.Is<GetBobbinsRequest>
  (r.Parameter1 == value1 && [...] & r.ParameterN == valueN);
mockedObject
  .Setup(mo => mo.GetBobbins(request))
  .Returns(someBobbins);
Run Code Online (Sandbox Code Playgroud)

但这似乎不起作用.我也尝试过:

Func<GetBobbinsRequest> request = () => It.Is<GetBobbinsRequest>
  (r.Parameter1 == value1 && [...] & r.ParameterN == valueN);
mockedObject
  .Setup(mo => mo.GetBobbins(request()))
  .Returns(someBobbins);
Run Code Online (Sandbox Code Playgroud)

但也没有喜悦.有什么办法可以将It样式对象保存为变量吗?或者我错过了一些其他明显的处理方式?

Mic*_*eld 7

而且......我找到了答案.这是Moq的比赛(上课):

创建自定义匹配器非常简单.您只需要创建一个方法,该方法使用匹配条件和可选的友好渲染表达式从调用Create返回值:

[Matcher]
public Order IsBigOrder()
{
    return Match<Order>.Create(
        o => o.GrandTotal >= 5000, 
        /* a friendly expression to render on failures */
        () => IsBigOrder());
}
Run Code Online (Sandbox Code Playgroud)

此方法可用于任何模拟设置调用:

mock.Setup(m => m.Submit(IsBigOrder()).Throws<UnauthorizedAccessException>();
Run Code Online (Sandbox Code Playgroud)

http://www.nudoq.org/#!/Packages/Moq/Moq/Match(T)


Pat*_*irk 5

关于您的问题为何不起作用的快速说明,因为我在看到您的答案之前就已将其写下:

It.Is实际上,每次调用最终都会返回default(T),因此存储它并在以后使用它与传递null或参数类型的默认值相同。

为什么它的原因是内联是因为调用It.Is的实际工作由设置在一个“模拟情境”的静态成员的呼吁Setup 最终 得到 各地使用。