Nunit 使用Verify确认Moq mock类中的预期参数值

Nunit 使用Verify确认Moq mock类中的预期参数值,nunit,moq,autofixture,Nunit,Moq,Autofixture,我试图验证是否使用预期的对象参数调用模拟中的方法。我正在使用Moq,nUnit,并且认为AutoFixture的相似性应该能够完成这项工作。 下面是我试图做的一个简化版本 有没有办法用AutoFixture实现这一点?是否有更好的方法来验证是否使用适当的参数调用了某些内容 重写A类中的Equals以比较属性值,并将Verify行更改为: barMock.Verify(m => m.Something(a)); 但是,我不希望像我的项目中的A那样覆盖每个类中的Equals namespac

我试图验证是否使用预期的对象参数调用模拟中的方法。我正在使用Moq,nUnit,并且认为AutoFixture的相似性应该能够完成这项工作。 下面是我试图做的一个简化版本

有没有办法用AutoFixture实现这一点?是否有更好的方法来验证是否使用适当的参数调用了
某些内容

重写
A
类中的Equals以比较属性值,并将
Verify
行更改为:

barMock.Verify(m => m.Something(a));
但是,我不希望像我的项目中的A那样覆盖每个类中的Equals

namespace Test
{
    using Moq;
    using NUnit.Framework;
    using Ploeh.SemanticComparison.Fluent;

    public class A
    {
        public int P1 { get; set; }
    }
    public interface IBar
    {
        void Something(A a);
    }

    public class Foo
    {
        public A Data { get; private set; }
        public void DoSomethingWith(IBar bar)
        {
            Data = new A { P1 = 1 };
            bar.Something(Data);
        }
    }

    [TestFixture]
    public class AutoFixtureTest
    {
        [Test]
        public void TestSample()
        {
            var foo = new Foo();
            var barMock = new Mock<IBar>();
            var a = new A { P1 = 1 };
            var expectedA = a.AsSource().OfLikeness<A>();

            foo.DoSomethingWith(barMock.Object);

            expectedA.ShouldEqual(foo.Data);   // passes
            barMock.Verify(m => m.Something(expectedA.Value));  // fails
        }
    }
}
名称空间测试
{
使用最小起订量;
使用NUnit.Framework;
使用Ploeh.SemanticComparison.Fluent;
公共A类
{
公共int P1{get;set;}
}
公共接口IBar
{
使某物无效(A);
}
公开课Foo
{
公共数据{get;private set;}
公共无效DoSomethingWith(IBar条)
{
数据=新的A{P1=1};
某物(数据);
}
}
[测试夹具]
公共类自动定影测试
{
[测试]
公共void TestSample()
{
var foo=new foo();
var barMock=new Mock();
var a=新的a{P1=1};
var expectedA=a.AsSource().OfLikeness();
foo.DoSomethingWith(barMock.Object);
expectedA.ShouldEqual(foo.Data);//通过
Verify(m=>m.Something(expectedA.Value));//失败
}
}
}

中的验证
默认情况下,Moq会检查参数的引用相等性,因此只有在测试和实现中提供相同的实例时(除非已重写
等于

在您的例子中,
expectedA.Value
只返回在测试中创建的
新A{P1=1}
,当然,它不是在
DoSomethingWith
中创建的同一个实例

您需要使用Moq的
It.Is
构造来正确地测试这一点,而不覆盖
Equals
(事实上,您根本不需要Autofixture):

barMock.Verify(m=>m.Something(It.Is(arg=>arg.P1==a.P1));
但是如果你有多个属性,比如P1,P2,P3。。。AutoFixture可能很有用:

barMock.Verify(m => m.Something(It.Is<A>(arg => expectedA.Equals(a))));
barMock.Verify(m=>m.Something(It.Is(arg=>expectedA.Equals(a));

因为您不需要手动写出所有属性的相等性检查。

如果升级到AutoFixture 2.9.1(或更新版本),您可以在相似性实例上调用CreateProxy方法,该实例将为目标类型发出动态代理

生成的动态代理覆盖等于使用相似性,这简化了语法(相当多)

以下是原始测试方法,已修改为使用相似性代理:

[Test]
public void TestSample()
{
    var foo = new Foo();
    var barMock = new Mock<IBar>();
    var expected = new A().AsSource().OfLikeness<A>().CreateProxy();
    expected.P1 = 1;

    foo.DoSomethingWith(barMock.Object);

    Assert.True(expected.Equals(foo.Data));     // passes
    barMock.Verify(m => m.Something(expected)); // passes
}
[测试]
公共void TestSample()
{
var foo=new foo();
var barMock=new Mock();

var expected=new A().AsSource().oflikenness.

+1特别是最后一个解决方案是正确的相似性方法。FWIW有一个工作项用于相似性的新功能,使其能够动态发出一个覆盖Equals的代理,这将大大简化上述语法:beauty,+1 applicated!
[Test]
public void TestSample()
{
    var foo = new Foo();
    var barMock = new Mock<IBar>();
    var expected = new A().AsSource().OfLikeness<A>().CreateProxy();
    expected.P1 = 1;

    foo.DoSomethingWith(barMock.Object);

    Assert.True(expected.Equals(foo.Data));     // passes
    barMock.Verify(m => m.Something(expected)); // passes
}