3

在我之前询问过 Autofixture 的CreateProxy 方法的问题中,发现了一个潜在的错误

我不认为这个失败的测试是因为这个,而是我对 Likeness.Without(...).CreateProxy() 语法如何工作的持续困惑。考虑以下失败的测试,在该测试中,我通过创建对象的新实例使原始测试 变得稍微复杂一些,并认为它的创建是SUT

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange: intent -> use the fixture-created Band as Object Mother
    var template = new Fixture().Create<Band>();

    // act: intent -> instantiated Band *is* the SUT
    var createdBand = new Band {Brass = template.Brass,
                                Strings = template.Brass};

    //   intent -> specify that .Brass should not be considered in comparison 
    var likeness = template.AsSource().OfLikeness<Band>().
        Without(x => x.Brass).CreateProxy(); // Ignore .Brass property

    // per [https://stackoverflow.com/a/15476108/533958] explicity assign
    // properties to likeness
    likeness.Strings = template.Strings;
    likeness.Brass = "foo"; // should be ignored

    // assert: intent -> check equality between created Band & template Band
    //         to include all members not excluded in likeness definition
    likeness.Should().Be(createdBand);          // Fails
    likeness.ShouldBeEquivalentTo(createdBand); // Fails
    Assert.True(likeness.Equals(createdBand));  // Fails
}

这是乐队:

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

之前的问题不够复杂,无法帮助我理解 the Sourceof theLikeness通常应该是什么。

源是否应该是SUT的输出,在这种情况下,它将与 AutoFixture 创建的模板实例进行比较?

或者源应该是 AutoFixture 创建的模板实例,在这种情况下它将与SUT的输出进行比较?

编辑:更正了测试中的错误

我意识到我错误地将属性分配给了template.Brass实例的和属性Brass 更新后的测试反映了更正,并且所有六个断言现在都通过了。StringsBandvar createdBand = new Band {Brass = template.Brass, Strings = template.Strings}

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange: intent -> use the fixture-created Band as Object Mother
    var template = new Fixture().Create<Band>();

    // act: intent -> instantiated Band *is* the SUT
    var createdBand = new Band {Brass = template.Brass, Strings = template.Strings};

    // likeness of created
    var createdLikeness = createdBand.AsSource().OfLikeness<Band>().
        Without(x => x.Brass).CreateProxy(); // .Brass should not be considered in comparison 

    // https://stackoverflow.com/a/15476108/533958 (explicity assign properties to likeness)
    createdLikeness.Strings = createdBand.Strings;
    createdLikeness.Brass = "foo"; // should be ignored

    // likeness of template
    var templateLikeness = template.AsSource().OfLikeness<Band>()
        .Without(x => x.Brass)
        .CreateProxy();
    templateLikeness.Strings = template.Strings;
    templateLikeness.Brass = "foo";

    // assert: intent -> compare created Band to template Band
    createdLikeness.Should().Be(template);
    createdLikeness.ShouldBeEquivalentTo(template);
    Assert.True(createdLikeness.Equals(template));

    templateLikeness.Should().Be(createdBand);
    templateLikeness.ShouldBeEquivalentTo(createdBand);
    Assert.True(templateLikeness.Equals(createdBand));
}
4

1 回答 1

3

你的意思是:

likeness.Should().BeAssignableTo<Band>(); // Returns true.

在提供的示例中,生成的代理是从Likeness派生的类型,使用语义比较算法Band覆盖。Equals

使用反射是:

createdBand.GetType().IsAssignableFrom(likeness.GetType()) // Returns true.

更新

createBand和模板实例不受该方法的影响。为什么他们应该?CreateProxy

使用 Likeness CreateProxy,您基本上可以创建一个自定义平等断言,允许您执行以下操作:

Assert.True(likeness.Equals(createdBand)); // Passed. 

没有它,原始的平等断言将失败:

Assert.True(template.Equals(createdBand)); // Failed.

但是,以下操作也会失败:

Assert.True(likeness.Equals(template));

它失败了,因为该Strings值是createdBand实例中的值。

这种行为是预期的,您可以Likeness直接使用以下方法进行验证:

 createdBand.AsSource().OfLikeness<Band>()
     .Without(x => x.Brass).ShouldEqual(template);

输出:

 The provided value `Band` did not match the expected value `Band`. The following members did not match:
      - Strings.
于 2013-03-22T07:21:50.303 回答