3

earlier question我询问了Autofixture的CreateProxy methodpotential bug被识别出来。使用Autofixture的CreateProxy来使用Likeness,SemanticComparison功能时遇到问题

我不认为这个失败的测试是因为这个,而是我对Likeness.Without(...)。CreateProxy()语法是如何工作的继续混淆。考虑下面失败的测试中,我通过创建对象的新实例,考虑到它的创作使original test非常轻微更加复杂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; } 
} 

我的earlier question不够复杂,无法帮助我理解Likeness的一般Source

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

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

编辑:修正了一个错误的测试

我意识到,我已经分配了错误的template.Brass属性BrassBand实例的Strings财产。更新后的测试反映了var 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)); 
} 
+0

关于明确指定属性,[这是怎么回事下一个版本还有待提高] (http://stackoverflow.com/questions/15470997/why-doesnt-simple-test-pass-using-autofixture-freeze-semanticcomparison-likene#comment22060162_15476108)。 – 2013-03-22 07:24:23

+0

@NikosBaxevanis谢谢你的工作!在此之前,我已经完成了你对我之前的问题的回答中所建议的内容,即在将要检查平等的实例中明确指定属性值,除了排除使用.Without(...)语法的相似性。我有这个部分吗? – Jeff 2013-03-22 17:04:31

+0

@Lumiris是的,这是正确的。 – 2013-03-22 19:52:21

回答

3

你是什么意思是:

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

在提供的例子,从Likeness生成的代理是一种从Band派生,使用语义对比算法重写Equals

使用反射那就是:

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

更新

createBand模板情况下不会受到CreateProxy方法。为什么他们应该?

对类似CreateProxy你基本上建立一个Custom Equality Assertion,可以让你做的事:

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

没有它,原来平等断言会失败:

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

然而,下面也将失败:

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

它失败了,因为th e 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. 
+0

是不是只是比较类型?我想比较类似性(从模板创建)和createdBand(从SUT创建)之间是否相等(所有成员除了像素创建中特别排除的成员)。我有足够的信心,他们将是相同的类型或可分配给我不想明确验证的相同类型。我会尝试更新这个问题,以便更清楚地了解这一点。 – Jeff 2013-03-22 16:57:11

+0

@Lirirris在更新后的测试中,您必须将'Likeness'代理(目标)与* template *实例(源代码)进行比较。 – 2013-03-22 20:26:49

+0

如果我更新为'likeness.Should().Be(template)',测试通过,但它不检查SUT输出('createdBand')。但是如果'createdBand'被用作相似的来源('var likeness = createdBand.AsSource()。OfLikeness ().Without(x => x.Brass).CreateProxy()'和'likeness.Strings = createdBand.Strings '),那么SUT的输出将通过相似性被引用,并且测试再次失败。我认为相似性必须完全由'createdBand'或完全从'template'组成,并且测试失败。对不起,如果我没有明显的东西 - 我真的想要得到它。 – Jeff 2013-03-22 22:13:19