[英]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
的某个值,如Guid
的Guid.Empty
, int
的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.