【问题标题】:Why doesn't simple test pass using AutoFixture Freeze, SemanticComparison Likeness and CreateProxy?为什么使用 AutoFixture Freeze、SemanticComparison Likeness 和 CreateProxy 的简单测试无法通过?
【发布时间】:2013-04-13 05:31:18
【问题描述】:

我试图了解如何使用一个简单类的两个实例来使用Likeness<T>()CreateProxy() 功能。

public class Band
{
    public string Strings { get; set; }
    public string Brass { get; set; }
}

在下面的测试中,我使用FixtureCreate<T> 一个Band 实例以及两个字符串属性的值。

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange
    var fixture = new Fixture();
    fixture.Customize(new AutoMoqCustomization());

    var original = fixture.Create<Band>();
    //   Brass something like --> "Brass65756b89-d9f3-42f8-88fc-ab6de5ae65cd"
    //   Strings something like --> "Strings7439fa1b-014d-4544-8428-baea66858940"

    // act
    var dupe = new Band {Brass = original.Brass, 
                         Strings = original.Strings};
    //   Brass same as original's like --> "Brass65756b89-d9f3-42f8-88fc-ab6de5ae65cd"
    //   Strings same as original's like --> "Strings7439fa1b-014d-4544-8428-baea66858940"

我尝试了许多不同的断言,但问题的症结似乎在于CreateProxy 方法没有填充Band 的属性,因此即使我尝试比较Band 的两个实例具有相同的属性值,来自CreateProxy 方法的实例始终具有空值。

    // assert
    var likeness = dupe.AsSource().OfLikeness<Band>()
                       .Without(x => x.Brass).CreateProxy();
    //   Brass & String properties are null using dupe as source of likeness (!)

    //var likeness = original.AsSource().OfLikeness<Band>()
    //                       .Without(x => x.Brass).CreateProxy();
    //   Brass & String properties are null using original as source of likeness (!)

    //Assert.True(likeness.Equals(original)); // Fails
    //Assert.True(original.Equals(likeness)); // Fails

    // below are using FluentAssertions assembly
    //likeness.Should().Be(original);           // Fails (null properties)
    //original.Should().Be(likeness);           // Fails (null properties)
    //likeness.ShouldBeEquivalentTo(original);  // Fails (null properties)
    //original.ShouldBeEquivalentTo(likeness);  // Fails (null properties)
}

我一定是做错了什么,但我已经阅读了我在 Ploeh 博客和 SO 上可以找到的所有内容,但找不到足够简单的示例来与我正在做的事情进行比较。有什么想法吗?

【问题讨论】:

    标签: autofixture semantic-comparison


    【解决方案1】:

    如果您在代理实例上分配值(在调用CreateProxy 方法之后),则测试通过:

    [Fact]
    public void Equality_Behaves_As_Expected()
    {
        // AutoMoqCustomization is not necessary.
        var original = new Fixture().Create<Band>();
    
        var likeness = original
            .AsSource()
            .OfLikeness<Band>()
            .Without(x => x.Brass)
            .CreateProxy();
    
        likeness.Brass = "foo"; // Ignored.
        likeness.Strings = original.Strings;
    
        Assert.True(likeness.Equals(original));
        likeness.Should().Be(original);
        likeness.ShouldBeEquivalentTo(original);
    }
    

    请记住,Likenesstarget 类型上创建了一个代理,并且只有该类型的实例会覆盖 Equals

    由于 source 类型保持不变,以下断言将不会成功:

    Assert.True(original.Equals(likeness));
    original.Should().Be(likeness);
    original.ShouldBeEquivalentTo(likeness);

    更新

    从 3.0.4 及更高版本开始,值会自动复制到代理实例(这意味着,likeness.Strings = original.Strings; 将自动发生)。

    【讨论】:

    • 但是为什么Assert.True(likeness.Equals(original)); 会失败? OP 指出这行代码也失败了。这不应该通过吗?
    • 是的。对于两个 代理 实例,相等断言是对称的,这意味着对于代理 xy x.Equals(y) 返回与 y.Equals(x) 相同的值。然而,由于在上面的测试中源类型没有被代理,所以只能使用代理的Equals。请注意,这允许您执行very flexible comparisons
    • @MarkSeemann CreateProxy 不会将属性值从目标类型复制到代理类型。 (创建代理后,必须分配属性值,然后进行比较。)
    • 我相信这是一个错误。我创建了github.com/AutoFixture/AutoFixture/issues/87 来跟踪它。
    • 目前,有一些工作正在进行中,以便CreateProxy 方法可以复制公共字段/属性。这样,就不需要在代理实例上分配值(在调用 CreateProxy 方法之后)。
    猜你喜欢
    • 2013-03-11
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多