gpt4 book ai didi

c# - Moq 设置不适用于方法调用后跟隐式转换

转载 作者:行者123 更新时间:2023-11-30 12:46:45 24 4
gpt4 key购买 nike

对于这个问题,考虑(创建)接口(interface):

public interface ITestMe
{
string TakeInt64(long x);
}

然后运行以下代码:

public void Test()
{
var mock1 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr1 = x => x.TakeInt64(2);
Console.WriteLine(expr1);
mock1.Setup(expr1).Returns("OK");
var s1 = mock1.Object.TakeInt64(2L); // OK

var mock2 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr2 = x => x.TakeInt64(DateTime.Today.Year / 1000);
Console.WriteLine(expr2);
mock2.Setup(expr2).Returns("OK");
var s2 = mock2.Object.TakeInt64(2L); // OK

var mock3 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr3 = x => x.TakeInt64((int)(DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Tuesday"));
Console.WriteLine(expr3);
mock3.Setup(expr3).Returns("OK");
var s3 = mock3.Object.TakeInt64(2L); // OK

var mock4 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr4 = x => x.TakeInt64(GetInt32());
Console.WriteLine(expr4);
mock4.Setup(expr4).Returns("OK");
//var s4 = mock4.Object.TakeInt64(2L); // MockException, All invocations on the mock must have a corresponding setup.

var mock5 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr5 = x => x.TakeInt64(int.Parse("2"));
Console.WriteLine(expr5);
mock5.Setup(expr5).Returns("OK");
//var s5 = mock5.Object.TakeInt64(2L); // MockException, All invocations on the mock must have a corresponding setup.

var mock6 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr6 = x => x.TakeInt64(GetInt32() + 0);
Console.WriteLine(expr6);
mock6.Setup(expr6).Returns("OK");
var s6 = mock6.Object.TakeInt64(2L); // OK

var mock7 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr7 = x => x.TakeInt64(1 * int.Parse("2"));
Console.WriteLine(expr7);
mock7.Setup(expr7).Returns("OK");
var s7 = mock7.Object.TakeInt64(2L); // OK
}

static int GetInt32()
{
return 2;
}

在所有七种情况下,我们都创建了一个表达式树,其中 TakeInt64 得到一个 int (Int32) 而不是 long(Int64)。然而,众所周知,存在从 intlong 的隐式转换,它将出现在表达式树中(expr1 除外,其中编译器为我们转换常量)。

上面的 s4s5 怎么不行?奇怪的是,如您所见,如果我们添加 0 或乘以 1,如 s6s7 的情况,有效(即使类型仍然是 int,隐式转换为 long)?

由于大小写 expr2,请在 3000 年之前回答。

最佳答案

我认为这是 Moq 中的错误。相关代码在MatcherFactory .具体来说,Convert 已从表达式中删除,以便可以进一步检查。当剩下的最顶层表达式节点是一个方法调用时,这个节点被惰性求值。当剩余的表达式不是方法调用时,整个表达式(包括 Convert!)被急切求值。

这意味着使用惰性求值,比较是在没有 Convert 的情况下完成的,并且 object.Equals(2, 2L)false。但是通过热切的评估,Convert 被考虑在内,因此您的代码可以正常工作。

我做了an attempt at fixing this ,这似乎解决了我的问题。

(哇,我差点以为我来不及了。)

关于c# - Moq 设置不适用于方法调用后跟隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18876436/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com