C# 没有它的Moq验证-什么样的比较?

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中,集合上的等于是从对象继

在使用带有Verify的Moq时,为了断言已使用指定参数调用了某个方法,可以使用不同的语法;一个是“It”语法,如下所示

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