0

アプリケーションのこの部分は、JSON との間で解析してオブジェクトに変換します。「PurchaseOrder」を作成し、それを JSON に変換して同じタイプのオブジェクトに戻し、リフレクションを使用して元の PurchaseOrder と最終的な PurchaseOrder の両方が同一であることを確認する単体テストを作成しました。

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(com.giltgroupe.purchaseorder.core.json.LineItemImpl@5b6ca395) vs Vector(com.giltgroupe.purchaseorder.core.json.LineItemImpl@3967ba17)

つまり、比較される 2 つのオブジェクトの 2 つの Vector は、内部の要素が異なります。これは、ケース クラスを標準クラスに変更すると、一部のパターン マッチ プロパティが失われ、コンテンツではなくオブジェクト アドレスが比較されるためだと理解しています。

LineItemImpl にいくつかのプロパティまたは注釈を追加して、これを修正する方法はありますか? それとも、リフレクション チェックを変更してベクトルにドリルダウンすることしかできませんか? 理想的には、単体テストを変更したくありません。

ありがとう!

4

1 に答える 1

1

ケースクラスに対して自動的に作成されるメソッド、equals が欠落していることがわかりました。

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

この場合、hashCode メソッドも定義する必要があります。これは、コードを実行するために必要ではありませんが、含まれていないと、後で奇妙な動作をする可能性があります。

override final def hashCode(): Int = ScalaRunTime.this._hashCode(LineItemJson.this)
于 2012-11-05T18:40:53.960 に答える