你可以存储一个'它' matcher对象作为变量,而不是内联定义? (MOQ)

时间:2014-12-10 13:56:08

标签: c# .net mocking moq

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

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

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

变为:

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

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

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

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

2 个答案:

答案 0 :(得分:7)

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

  

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

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

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

mock.Setup(m => m.Submit(IsBigOrder()).Throws<UnauthorizedAccessException>();

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

答案 1 :(得分:5)

快速解释为什么你在问题中所拥有的东西不起作用,因为我在看到你的答案之前写了它:

It.Is的调用实际上以returning default(T) every time结束,因此将其存储并稍后使用它将与传递null或参数类型的默认值相同。

必须内联的原因是因为It.Is的调用实际上由setting a static member in a "mock context"调用Setup eventually gets {{ 3}}使用。