【问题标题】:Why are nested classes ignored in FluentAssertions when using "Including"?为什么使用“包含”时 FluentAssertions 中的嵌套类会被忽略?
【发布时间】:2016-06-29 19:52:07
【问题描述】:

为了说明问题,请考虑以下三个类:

class Orange
{
    public String color { get; set; }
}
class Foo
{
    public Int32 size { get; set; }
    public Orange orange { get; set; }
}
class Bar
{
    public Int32 size { get; set; }
    public Orange orange { get; set; }
}

如果我创建 Foo 和 Bar 的实例,并将它们的 Orange 实例设置为不同,然后进行断言(不使用“包含”),则断言按预期工作;它找到了“red”和“bff”之间的区别:

Foo foo = new Foo() { size = 3 };
foo.orange = new Orange() {color = "red" }; 

Bar bar = new Bar() { size = 3 };
bar.orange = new Orange() { color = "bff" };

foo.ShouldBeEquivalentTo(bar);  // assertion fails, as expected

但是,如果我做同样的断言,同时通过“包含”明确告诉 FluentAssertions 要比较什么,断言不会捕捉到 Orange 的差异:

foo.ShouldBeEquivalentTo(bar, options => options
    .Including(o => o.size)
    .Including(o => o.orange)
    );   // assertion does not fail, why?

【问题讨论】:

  • 我想我可能已经回答了我自己的问题 - 我想我需要这样做:.Including(o => o.orange.color)
  • 你用的是什么版本?
  • 4.2.2 我的“修复”(即 o.orange.size)似乎适用于简单的情况。但是在我弄清楚之后,我想使用包括来断言一个包含对象数组的字段..并且断言对此不起作用。这可能与我尝试包含数组的方式有关:.Including(o => o.my_object.arraylist[0].field_of_interest)。我认为输入 [0] 感觉不对,但这是我编译它的唯一方法

标签: c# .net fluent-assertions


【解决方案1】:

您可以使用ComparingByValue

foo.ShouldBeEquivalentTo(bar, options => options
    .Including(o => o.size)
    .Including(o => o.orange)
    .ComparingByValue<Orange>());

然后它失败了。

您已包含 orange 用于比较对象的属性,并且比较对象是基于它们的属性,并且您未包含要比较的 orange 的任何属性,因此假定 foo.orange 等于 bar.orange

添加 CompareByValue&lt;Orange&gt; 可以根据 Equals 方法比较 Orange 实例。所以默认会做参考比较。

你应该为Orange覆盖Equals

class Orange
{
    public String color { get; set; }

    public override bool Equals(object obj)
    {
        var orange = obj as Orange;
        return Equals(orange);
    }

    protected bool Equals(Orange other)
    {
        return other != null && 
            string.Equals(color, other.color);
    }

    public override int GetHashCode()
    {
        return color?.GetHashCode() ?? 0;
    }
}

现在您可以使用这种方法比较偶数列表。

var foo = new Foo() { size = 3 };
var o1 = new Orange { color = "a" };
var o2 = new Orange { color = "a" };
var o3 = new Orange { color = "b" };
var o4 = new Orange { color = "b" };
foo.orange = new List<Orange>() { o1, o3 };

Bar bar = new Bar() { size = 3 };
bar.orange = new List<Orange>() { o1, o4 };

foo.ShouldBeEquivalentTo(bar);

foo.ShouldBeEquivalentTo(bar, options => options
    .Including(x => x.size)
    .Including(x => x.orange)
    .ComparingByValue<Orange>());

【讨论】:

  • 查看我对原始帖子的评论。我发现指定 orange.color 确实按预期工作,但我认为您的 .ComparingByValue 会导致比较所有橙色,这可能是大多数人想要的。另外参考我上面的评论,如果橙色是对象列表而不是对象,您认为 ComparingByValue 会起作用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2018-10-05
  • 1970-01-01
相关资源
最近更新 更多