C# 没有它的Moq验证-什么样的比较?
在使用带有Verify的Moq时,为了断言已使用指定参数调用了某个方法,可以使用不同的语法;一个是“It”语法,如下所示C# 没有它的Moq验证-什么样的比较?,c#,moq,verify,C#,Moq,Verify,在使用带有Verify的Moq时,为了断言已使用指定参数调用了某个方法,可以使用不同的语法;一个是“It”语法,如下所示 mock.Verify(c => c.SomeMethod(It.Is<string>(s => s == ExpectedString))); 结果应该是一样的。从我在不同论坛上发现的情况来看,区别在于后者是一种身份检查(reference equals)(值类型除外) 但是,我的问题是参数的类型是否为集合类型。在.NET中,集合上的等于是从对象继
mock.Verify(c => c.SomeMethod(It.Is<string>(s => s == ExpectedString)));
结果应该是一样的。从我在不同论坛上发现的情况来看,区别在于后者是一种身份检查(reference equals)(值类型除外)
但是,我的问题是参数的类型是否为集合类型。在.NET中,集合
上的等于
是从对象
继承而来的,因此以下验证:
mock.Verify(c => c.SomeMethod(new Collection<string> { ExpectedString }));
mock.Verify(c=>c.SomeMethod(新集合{ExpectedString}));
由于集合在验证中实例化,因此不可能是在生产代码中实例化的同一实例,因此不可能通过。然而,它是有效的,这表明Moq做了一个收集评估或类似的事情,与我能找到的信息相反
下面是一个代码示例,演示了该行为,测试通过了,但我认为如果Moq使用了reference equals比较,它应该失败
[TestMethod]
public void Test()
{
var mock = new Mock<IPrint>();
const int ExpectedParam = 1;
var test = new TestPrinter { Printer = mock.Object, Expected = ExpectedParam };
test.Do();
mock.Verify(c => c.Print(new Collection<int> { ExpectedParam }));
}
public interface IPrint
{
void Print(Collection<int> numbers);
}
public class TestPrinter
{
public IPrint Printer { get; set; }
public int Expected { get; set; }
public void Do()
{
Printer.Print(new Collection<int> { Expected });
}
}
[TestMethod]
公开无效测试()
{
var mock=new mock();
const int ExpectedParam=1;
var test=newtestprinter{Printer=mock.Object,应为=ExpectedParam};
test.Do();
验证(c=>c.Print(新集合{ExpectedParam}));
}
公共接口IPrint
{
作废打印(收集编号);
}
公共类测试打印机
{
公共IPrint打印机{get;set;}
公共int应为{get;set;}
公营部门
{
Printer.Print(新集合{预期});
}
}
有人知道这是否是Moq(版本4.1)的预期行为吗?行为是否在某些版本级别发生了更改?这是过去的(版本3.0.203.1)
如果moq找到一个IEnumerable
,它将使用它来比较实际参数和设置中使用的参数,否则它只使用Equals
相关代码位:
internal class ConstantMatcher : IMatcher
{
...
public bool Matches(object value)
{
if (object.Equals(constantValue, value))
{
return true;
}
if (this.constantValue is IEnumerable && value is IEnumerable)
{
return this.MatchesEnumerable(value);
}
return false;
}
private bool MatchesEnumerable(object value)
{
var constValues = (IEnumerable)constantValue;
var values = (IEnumerable)value;
return constValues.Cast<object>().SequenceEqual(values.Cast<object>());
}
}
内部类常量匹配器:IMatcher
{
...
公共布尔匹配(对象值)
{
if(object.Equals(constantValue,value))
{
返回true;
}
if(this.constantValue为IEnumerable&&value为IEnumerable)
{
返回此.MatchesEnumerable(值);
}
返回false;
}
私有布尔匹配可计算(对象值)
{
var constValues=(IEnumerable)constantValue;
变量值=(IEnumerable)值;
返回constValues.Cast().SequenceEqual(values.Cast());
}
}
internal class ConstantMatcher : IMatcher
{
...
public bool Matches(object value)
{
if (object.Equals(constantValue, value))
{
return true;
}
if (this.constantValue is IEnumerable && value is IEnumerable)
{
return this.MatchesEnumerable(value);
}
return false;
}
private bool MatchesEnumerable(object value)
{
var constValues = (IEnumerable)constantValue;
var values = (IEnumerable)value;
return constValues.Cast<object>().SequenceEqual(values.Cast<object>());
}
}