简体   繁体   English

Moq的It.IsAny怎么样? <T> ()实施

[英]How is Moq's It.IsAny<T>() implemented

For C#'s Moq, I went in through debugger, and noticed It.IsAny<T>() just compiles to a certain value of T , like Guid.Empty for Guid s, 0 for int s, etc. 对于C#的Moq,我通过调试器进入,并注意到It.IsAny<T>()只是编译为T的某个值,如GuidGuid.Emptyint的0,等等。

How does Moq tell the difference between an It.IsAny<T> and the value that it compiles to? Moq如何区分It.IsAny<T>与它编译的值之间的It.IsAny<T>

Taking base in the GitHub source code , what's really being matched is a given predicate of type Predicate<T> (or Func<T, bool> if you like): GitHub源代码为基础 ,真正匹配的是谓词类型Predicate<T> (或Func<T, bool>如果你喜欢):

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

It checks if the value is null, or if the value is the same type as the TValue argument for IsAny<TValue> using Type.IsAssignableFrom . 它检查value是否为null,或者该value是否与使用Type.IsAssignableFrom的 IsAny<TValue>TValue参数的类型相同。

It then returns the default(T) value of the type to allow the mocked method to correctly match the signature. 然后,它返回类型的default(T)值,以允许模拟方法正确匹配签名。 And as pointed out by DavidH, you can't use null for value types, which is why using default(T) is preferred as a generic return value. 正如DavidH所指出的,你不能对值类型使用null,这就是为什么使用default(T)作为泛型返回值的首选。

The lambdas we use when we Setup mocks in Moq are not the usual delegates, they are expression trees . 我们在Moq中Setup模拟时使用的lambda 不是通常的委托,它们是表达式树 The It.Is<> method is just a place-holder. It.Is<>方法只是一个占位符。 It is not necessarily actually called. 它实际上不一定被称为。 It is not important if it returns default(T) or just throws a NotSupportedException or something else. 如果它返回default(T)或仅抛出NotSupportedException或其他内容并不重要。 Let me give an example: 让我举个例子吧:

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);
  }
}

Not too interesting, but it should show that with expression trees Expression<...> you can see what method was used, and not just the returned value. 不太有趣,但它应该表明,使用表达式Expression<...>您可以看到使用了什么方法,而不仅仅是返回的值。 Find out more on how to examine an expression tree on MSDN, Expression Trees . 详细了解如何检查MSDN上的表达式树,表达式树

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM