2012-11-03 38 views
0

我的應用程序的這部分解析爲JSON並將其從我的對象中解析出來。我創建,創建一個「的PurchaseOrder」,它轉化爲JSON並將其轉換成相同類型的對象,並使用反射單元測試,以檢查原始和最終的PurchaseOrder是相同的:Scala中的反射代碼不會深入到矢量中

val purchaseOrderJson = PurchaseOrderJson.toJson(purchaseOrder) 
val clientPurchaseOrder = PurchaseOrderJson.fromJson(purchaseOrderJson) 

val reflectionCheck = classOf[PurchaseOrder].getMethods.forall { 
(method: Method) => 
    if (!method.invoke(purchaseOrder).equals(method.invoke(clientPurchaseOrder))) { 
     println("%s unequal: %s vs %s".format(method.getName, method.invoke(purchaseOrder), method.invoke(clientPurchaseOrder))) 
     false 
    } else { 
     true 
    } 
} 

這是JSON:

"purchaseOrders": [{ 
    "id": "522423", 
    "lineItems": [{ 
     "notes": "Important item", 
     "origin": "Spain" 
     },{ 
     "notes":null, 
     "origin": "Italy" 
    }] 
}] 

我有對象定義爲性狀:

trait PurchaseOrder { 
    def id: String 
    def lineItems: Vector[LineItem] 
} 

trait LineItem { 
    def notes: Option[String] 
    def origin: String 
} 

而如下的實現:

class PurchaseOrderJson(
    @(JsonProperty @field) override val id: String, 
    @(JsonProperty @field) override val lineItems: Vector[LineItemImpl] 
) extends PurchaseOrder { 
    def this() = this("",Vector.empty[LineItemImpl]) 
} 

case class LineItemImpl(notes: Option[String]) extends LineItem 

現在:)我的問題是我必須添加很多字段到LineItem和編譯器抱怨我不能有超過22個參數在案例類。所以我所做的是改寫LineItemImpl看起來像這樣:

class LineItemImpl(
    @(JsonProperty @field) override val notes: Option[String] = None 
) extends LineItem { 
    def this() = this(None) 
} 

但現在我在反射單元測試得到一個錯誤:

lineItems unequal: Vector([email protected]) vs Vector([email protected]) 

這意味着這兩個對象的兩個向量進行比較不同在元素裏面。我理解這是因爲當我將case類更改爲標準類時,它會丟失一些模式匹配屬性,所以現在它將比較對象地址而不是內容。

有什麼辦法可以解決這個問題,爲LineItemImpl添加更多的屬性或註解?或者我能做的唯一事情就是修改我的反射檢查以深入到矢量?理想情況下,我不想修改單元測試。

謝謝!

+0

由於沒有相等的定義(方法等於),因此失敗。真的不明白爲什麼這裏需要反射 – Arjan

+0

你是對的!剛剛找到解決辦法 – Miguel

回答

1

我發現我失蹤是爲case類自動創建一個方法,等於

override final def equals (other:Any):Boolean = {} 

在這種情況下,我還需要定義hashCode方法,沒有必要爲我的代碼運行,但它如果不包括,可能會出現奇怪的行爲:

override final def hashCode(): Int = ScalaRunTime.this._hashCode(LineItemJson.this)