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