2016-02-26 64 views
5

我有相當複雜的對象結構(帶有一堆原始字段和對象引用),並且想要測試除-a部分之外的所有字段。舉個例子;Hamcrest - 優雅的方式來測試具有相同propertyity值的複雜對象

ComplexObject actual = generateMagically("someInput"); 
ComplexObject expected = ActualFunction.instance.workMagically(actual); 

// we want to be sure that workMagically() would create a new ComplexObject 
// with some fields are different than "actual" object. 

// assertThat(actual, samePropertyValuesAs(expected)); would check all fields. 
// what I want is actually; - notice that "fieldName1" and "fieldName2" are 
// primitives belong to ComplexObject 
assertThat(actual, samePropertyValuesExceptAs(expected, "fieldName1", "fieldName2")) 

由於我不想手動檢查所有字段,我相信必須有一種方法來優雅地編寫測試。有任何想法嗎?

乾杯。

+0

所以,你有兩個袋* *的對象,想進行深度比較呢? – Raffaele

+0

不確定要叫他們包對象,有許多原始字段和其他對象引用。我想跳過的字段是屬於ComplexObject的原始字段。我們可以說這將是一個深刻的比較。 – tugcem

+0

你是否只想''samePropertyValuesExceptAs'的Matcher實現作爲這個問題的答案?如果是這樣的話,你可以創建'org.hamcrest.beans.SamePropertyValuesAs '的副本,並添加另一個構造函數/靜態工廠方法,該方法將刪除被排除的屬性進行測試。 – SpaceTrucker

回答

0

一般來說,我看到兩個解決方案,如果ComplexObject可以自己修改。

您可以引入一個界面,該界面代表ActualFunction正在更改的ComplexObject的屬性。然後您可以測試該新界面的所有屬性都已更改。這將需要ComplexObject實現該新界面。

另一種方法是用包含所有這些屬性的新類型的新屬性替換ActualFunction更改的ComplextObject的屬性。那麼更好的設計就是讓ActualFunction返回新類型的一個實例。

+0

Thanks SpaceTrucker。(1 )我認爲在域對象中實現一個接口僅僅用於測試目的不是最佳實踐。(2)對於另一種方法,您實際上提供了添加一個新屬性(我假設有一個新對象),它已經更新了屬性?再次改變對象只是爲了測試,我猜不。 – tugcem

+0

@tugcem這不僅是關於測試,而是關於使'ActualFunction'的效果更加明顯,而且它所表示的功能更具表現力。例如,如果「ActualFunction」的實現將改變爲也修改另一個屬性,那麼如果使用我的第二種方法,因爲新類型將獲得該新屬性,則此效果將立即可見。 – SpaceTrucker

+0

我實際上並不需要在workMagically()函數中添加額外的表達式或可見性來更改屬性。事實上,我們不想對更新字段做任何明確的說明,並期望這個類的用戶意識到這一點。 – tugcem

0

上次我有類似的要求我得出的結論是,手動編寫代碼和測試以斷言某些值更新本身就很容易且容易出錯。

我將包對象中的字段外化,並在編譯時爲包類本身和複製器生成Java源文件。通過這種方式,您可以測試實際的代碼(生成器),並在一個地方準確定義域的實際定義,以便複製代碼不會過時。

描述該屬性可以是任何東西,你是舒服,從JSON-架構XML和Java本身(Java示例如下 - 自定義的註釋是從發電機消耗)語言

public class MyBag { 
    @Prop public int oh; 
    @Prop public String yeah; 
} 
7

你應該看看shazamcrest,一個很棒的Hamcrest擴展,它提供了你所需要的。

assertThat(expected, sameBeanAs(expectedPerson).ignoring("fieldName1").ignoring("fieldName2")); 

https://github.com/shazam/shazamcrest#ignoring-fields

+1

如果有人想知道'''sameBeanAs''在哪裏,它在 '''com.shazam.shazamcrest.matcher.Matchers''類中。 –

相關問題