Moq的It.IsAny <t>()如何实现</t>

时间:2013-11-17 23:42:02

标签: c# moq

对于C#的Moq,我通过调试器进入,并注意到It.IsAny<T>()只编译为T的某个值,如Guid.EmptyGuid,0为{ {1}}等等。

Moq如何判断int与其编译的值之间的区别?

2 个答案:

答案 0 :(得分:7)

GitHub source code中取得基础,真正匹配的是Predicate<T>类型的给定谓词(或Func<T, bool>如果您愿意):

value => value == null || typeof(TValue).IsAssignableFrom(value.GetType())

它检查value是否为空,或者value是否与使用Type.IsAssignableFrom TValue的{​​{1}}参数的类型相同。

然后返回该类型的default(T)值,以允许模拟方法正确匹配签名。正如DavidH所指出的,你不能对值类型使用null,这就是为什么首选使用default(T)作为泛型返回值。

答案 1 :(得分:6)

我们在Moq中Setup进行模拟时使用的lambda是通常的委托,它们是 表达式树 It.Is<>方法只是一个占位符。它实际上不一定被称为。如果它返回default(T)或仅抛出NotSupportedException或其他内容并不重要。让我举个例子:

interface IMyFace
{
  void MethodToTest(object obj);
}

static class Test
{
  public static void Main()
  {
    Setup<IMyFace>(x => x.MethodToTest(null));
    Setup<IMyFace>(x => x.MethodToTest(MyAnyA<object>()));
    Setup<IMyFace>(x => x.MethodToTest(MyAnyB<object>()));
  }

  public static TArg MyAnyA<TArg>()
  {
    // never runs
    return default(TArg);
  }
  public static TArg MyAnyB<TArg>()
  {
    // never runs
    return default(TArg);
  }

  public static void Setup<T>(Expression<Action<T>> expr) where T : class
  {
    Console.WriteLine("The expr was: " + expr);
  }
}

不太有趣,但它应该表明使用表达式树Expression<...>,您可以看到使用了什么方法,而不仅仅是返回的值。详细了解如何在MSDN, Expression Trees上检查表达式树。