对于C#的Moq,我通过调试器进入,并注意到It.IsAny<T>()
只编译为T
的某个值,如Guid.Empty
为Guid
,0为{ {1}}等等。
Moq如何判断int
与其编译的值之间的区别?
答案 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上检查表达式树。