我在单元测试中遇到了一个奇怪的问题,关于JSON中的case类的序列化/反序列化。我正在使用play-json (2.5.10)
,我为我的活动定义了一个模型:
case class BFFEvent
(
startTime: Long,
endTime: Long,
eventType: BFFEventType.Value, // just an enum
payload: Option[Payload]
)
object BFFEvent {
implicit val BFFEventFormat = Json.format[BFFEvent]
}
Payload
是一个包含许多子类型的ADT,但我只提出了冲突的案例类:
sealed trait Payload
case class UserFlag
(
flag: Option[BFFEventFlag],
freeText: Option[String],
source: Option[BFFEventSource],
timestamp : Option[Timestamp]
) extends Payload
case class CommunicationMode(mode: Int) extends Payload
implicit val payloadReads = {
val userFlag = Json.reads[UserFlag]
val communicationMode = Json.reads[CommunicationMode]
__.read[UserFlag](userFlag).map(x => x: Payload) |
__.read[CommunicationMode](communicationMode).map(x => x: Payload)
}
implicit val payloadWrites = Writes[Payload] {
case userFlag: UserFlag => Json.writes[UserFlag].writes(userFlag)
case communicationMode: CommunicationMode => Json.writes[CommunicationMode].writes(communicationMode)
}
在单元测试中,我检查是否可以读/写我的有效载荷模型的JSON:
val communicationMode = BFFEvent(0, 0, BFFEventType.COMMUNICATIONMODE, Some(CommunicationMode(0)))
it should "serialize and deserialize a CommunicationMode" in {
val validatedJSON = Json.toJson(communicationMode).validate[BFFEvent]
validatedJSON should be(JsSuccess(communicationMode))
}
测试输出:
BFFEvent(0,0,COMMUNICATIONMODE,Some(CommunicationMode(0)))
JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(UserFlag(None,None,None,None))),)
JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(UserFlag(None,None,None,None))),) was not equal to JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(CommunicationMode(0))),)
ScalaTestFailureLocation: com.bioserenity.bff.test.TEST_BFF_MODELS_SERIALIAZER$$anonfun$1 at (TEST_BFF_MODELS_SERIALIAZER.scala:81)
Expected :JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(CommunicationMode(0))),)
Actual :JsSuccess(BFFEvent(0,0,COMMUNICATIONMODE,Some(UserFlag(None,None,None,None))),)
虽然json转换的输入是带有BFFEvent
有效负载的CommunicationMode
,但它转换为UserFlag
。我认为问题来自于payloadReads
函数中的匹配顺序,但改变匹配案例的顺序会产生另一种混淆,所以如果有人以前遇到过这个问题,他能否给我一个解决它或更好的解决方案,一个解决方案?