This part of my application parses to and from a JSON into my objects. I created a unit test that creates a ‘PurchaseOrder’, transforms it into JSON and transforms it back into the same type of object, and uses reflection to check both the original and the final PurchaseOrder are identical:
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
}
}
This is the JSON:
"purchaseOrders": [{
"id": "522423",
"lineItems": [{
"notes": "Important item",
"origin": "Spain"
},{
"notes":null,
"origin": "Italy"
}]
}]
I have the objects defined as traits:
trait PurchaseOrder {
def id: String
def lineItems: Vector[LineItem]
}
trait LineItem {
def notes: Option[String]
def origin: String
}
And the implementations as follows:
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
Now 🙂 my problem is I have to add a LOT of fields to LineItem and the compiler complains that I can’t have more than 22 params in a case class. So what I did is rewrite LineItemImpl to look like this:
class LineItemImpl(
@(JsonProperty @field) override val notes: Option[String] = None
) extends LineItem {
def this() = this(None)
}
But now I get an error in my reflection unit test:
lineItems unequal: Vector(com.giltgroupe.purchaseorder.core.json.LineItemImpl@5b6ca395) vs Vector(com.giltgroupe.purchaseorder.core.json.LineItemImpl@3967ba17)
That means the two Vectors in the two objects being compared differ in the element inside. I understand this is because when I change the case class to standard class it looses some pattern match properties so now it’s comparing the object address instead of the content.
Is there any way to fix this adding some more properties or annotations to LineItemImpl? Or the only thing I can do is modify my reflection check to drill down into the Vectors? Ideally I don’t want to modify the unit test.
Thanks!
I found out that I was missing a method that is created automatically for case classes, equals
In this case I also need to define the hashCode method, not necessary for my code to run but it might give weird behavior down the road if not included: