AutoFixture - 喜欢。复杂对象的比较 [英] AutoFixture - Likeness. Comparison of complex objects

查看:203
本文介绍了AutoFixture - 喜欢。复杂对象的比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图比较2个复杂的对象与AutoFixture的 OfLikeness 但不幸的是没有成功。当比较嵌套对象(也与 OfLikeness )工作原理正常,比较主对象结果与错误说,子对象不匹配。我假设问题是Likeness只应用语义比较器到主对象和嵌套对象使用默认Equal实现比较检查参考匹配(可能是我的假设是错误?)。

I am trying to compare 2 complex objects with AutoFixture's OfLikeness but unfortunately without success. While comparing nested objects( also with OfLikeness) works as expected, comparing a master object results with error saying that child objects don't match. I assume that the problem is that Likeness apply semantic comparrer only to a master object and nested objects are compared using default Equal implementation which checks for reference match(May be my assumption is wrong?).

这可以澄清我想达到的目的:

This could clarify what I am trying to achieve:

public class ComplexMasterObject{
    public ChildFirst child1 {get;set;}
    public ChildSecond child2 {get;set;}
    public string SimpleProp {get;set;}
}

public class ChildFirst {
    public string SomeStringProp1 {get;set;}
    public int  SomeIntProp1 {get;set;}
}

public class ChildSecond {
    public string SomeStringProp1 {get;set;}
    public int  SomeIntProp1 {get;set;}
}

测试:

public void TestLikeness_Success()
{
     var expected = new ComplexMasterObject {
         Child1 = new ChildFirst {
             SomeStringProp1 = "ChildFirst SomeStringProp1",
             SomeIntProp1 = 1
         },
         Child2 = new ChildSecond {
             SomeStringProp1 = "ChildSecond SomeStringProp1",
             SomeIntProp1 = 2
         },
         SimpleProp = "ComplexMasterObject SimpleProp"
     };

     var input = new ComplexMasterObject {
         Child1 = new ChildFirst {
             SomeStringProp1 = "ChildFirst SomeStringProp1",
             SomeIntProp1 = 1
         },
         Child2 = new ChildSecond {
             SomeStringProp1 = "ChildSecond SomeStringProp1",
             SomeIntProp1 = 2
         },
         SimpleProp = "ComplexMasterObject SimpleProp"
     };

     var child1Likeness = expected.Child1.AsSource().OfLikeness<ChildFirst>();
     var child2Likeness = expected.Child2.AsSource().OfLikeness<ChildSecond>();

     var masterLikeness = expected.AsSource().OfLikeness<ComplexMasterObject>();
     child1Likeness.ShouldEqual(input.Child1); //Passes
     child2Likeness.ShouldEqual(input.Child2); //Passes

     masterLikeness.ShouldEqual(input); 
     // The provided value `ComplexMasterObject` did not match the expected value `ComplexMasterObject`. The following members did not match:
  - Child1.
  - Child2.
}

当我序列化 expected 输入对象到JSON并比较结果,它们是相同的。

When I serialize expected and input objects to JSON and compare the results, they are identical.

我试图使用相似性,它也不工作:

I tried to use Resemblance, But it didn't work either:

var proxy = expected.AsSource().OfLikeness<ComplexMasterObject>().CreateProxy();
proxy.Equals(input); // returns false

如何对包含嵌套复杂属性的复杂对象执行语义比较?

How can perform a semantic comparison on complex object including nested complex properties?

提前感谢。

推荐答案

复杂的结构对象在C#

Complex structural object-equality in C# (with classes) is most of the times cumbersome, because classes use reference equality by default.

是可能的,虽然可以执行复杂的结构化对象 - 平等,使用AutoFixture附带的语义比较包(但作为单独的NuGet包分发)。

It is possible though to perform complex structural object-equality, using the SemanticComparison package that comes with AutoFixture (but gets distributed as a separate NuGet Package).

示例: 语义比较器< T>

[Fact]
public void TestComplexClassEquality()
{
    // Arrange
    var value = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var other = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var sut =
        new SemanticComparer<ComplexMasterObject>(
            new MemberComparer(
                new AnyObjectComparer()),
            new MemberComparer(
                new ChildFirstComparer()),
            new MemberComparer(
                new ChildSecondComparer()));

    // Act
    var actual = sut.Equals(value, other);

    // Assert
    Assert.True(actual);
}

示例: ; T> 及其相似代理

[Fact]
public void TestComplexClassEqualityResemblance()
{
    // Arrange
    var value = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var other = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var likeness =
        new Likeness<ComplexMasterObject>(
            value,
            new SemanticComparer<ComplexMasterObject>(
                new MemberComparer(
                    new AnyObjectComparer()),
                new MemberComparer(
                    new ChildFirstComparer()),
                new MemberComparer(
                    new ChildSecondComparer())));
    var sut = likeness.ToResemblance();

    // Act
    var actual = sut.Equals(other);

    // Assert
    Assert.True(actual);
}

对象定义 b

public sealed class AnyObjectComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        return object.Equals(x, y);
    }

    public int GetHashCode(object obj)
    {
        return obj.GetHashCode();
    }
}

public sealed class ChildFirstComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        var value = x as ChildFirst;
        var other = y as ChildFirst;

        if (value == null || other == null)
            return false;

        return value.SomeIntProp1    == other.SomeIntProp1
            && value.SomeStringProp1 == other.SomeStringProp1;
    }

    public int GetHashCode(object obj)
    {
        return obj.GetHashCode();
    }
}

public sealed class ChildSecondComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        var value = x as ChildSecond;
        var other = y as ChildSecond;

        if (value == null || other == null)
            return false;

        return value.SomeIntProp1    == other.SomeIntProp1
            && value.SomeStringProp1 == other.SomeStringProp1;
    }

    public int GetHashCode(object obj)
    {
        return obj.GetHashCode();
    }
}

这篇关于AutoFixture - 喜欢。复杂对象的比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆