user14028818
user14028818

Reputation:

Scala test issues

I am new to Scala and writing test cases using Scala test and spray json. My code is as follows:

case class MyModel(Point1: String,
                          Point2: String,
                          Point3: Option[NewModel] = None)


case class NewModel(Point4: Boolean,
                          Point5: Boolean,
                          Point6: Boolean)

it should "serialise/deserialize a MyModel to JSON" in {
    val json= """{"Point1":"","Point3":[],"Point2":""}""".parseJson
    val myModelViaJson= json.convertTo[MyModel]

    myModelViaJson.Point1 shouldBe ""
    myModelViaJson.Point3.head.point4 shouldBe true
    myModelViaJson.Point2 shouldBe ""
}

I am getting following error on running test case

should serialise/deserialize a MyModel to JSON *** FAILED ***
[info]   spray.json.DeserializationException: Object expected in field 'point4'
[info]   at spray.json.package$.deserializationError(package.scala:23)
[info]   at spray.json.ProductFormats.fromField(ProductFormats.scala:63)
[info]   at spray.json.ProductFormats.fromField$(ProductFormats.scala:51)

How to solve this?

Upvotes: 0

Views: 102

Answers (2)

Tomer Shetah
Tomer Shetah

Reputation: 8529

Just to elaborate the correct answer by @Tim. There is incompatibility between the provided Json, and the model. The json has Point3 as an array, while in MyModel it is Option[NewModel]. Therefore, the first cannot be deserialised into the latter. There are many ways to solve it, which depends on what you want.

  1. The easiest, remove Point3 from the Json:

    val json= """{"Point1":"","Point2":""}""".parseJson
    val myModelViaJson= json.convertTo[MyModel]
    

    It will produce MyModel(,,None)

  2. Change the Json to have NewModel:

    val json= """{"Point1":"","Point3":{ "Point4": true, "Point5": true, "Point6": true },"Point2":""}""".parseJson
    val myModelViaJson= json.convertTo[MyModel]
    

    Which produces MyModel(,,Some(NewModel(true,true,true)))

  3. In case you really meant to have array there, you can change the MyModel class:

    case class MyModel(Point1: String,
                       Point2: String,
                       Point3: Option[Seq[NewModel]] = None)
    

    Then the following:

    val json= """{"Point1":"","Point3":[],"Point2":""}""".parseJson
    val myModelViaJson= json.convertTo[MyModel]
    

    produces: MyModel(,,Some(List()))

Upvotes: 0

Tim
Tim

Reputation: 27356

Your JSON sets the value of Point3 to [] which is an empty array, but in the Scala it should be a NewModel object (hence "Object expected").

The use of Option in MyModel says that the field might be missing from the JSON, in which case the extracted value will be None. If the Point3 field is present in the JSON, it should contain the JSON for a NewModel, and the field will then be Some(<NewModel instance>).

Upvotes: 2

Related Questions