我试图使用json4s来解析一个简单的Json,发现它在我的程序的Main类中可以工作,但由于某些原因,在单元测试中不能工作。下面是一个最小的例子。
build. sbt:
ThisBuild / scalaVersion := "2.13.2"
lazy val validatorbroken = (project in file("."))
.settings(
name := "validatorbroken",
)
libraryDependencies ++= Seq(
"org.json4s" %% "json4s-jackson" % "3.7.0-M4",
"org.scalatest" %% "scalatest" % "3.1.2" % "test",
)
包含case类定义和函数的文件。
package validatorbroken
import org.json4s._
import org.json4s.jackson.JsonMethods._
case class EasyInput(file: String, sheet: String)
object ProcessInput {
import Main.formats
def captureEasyInput(s: String): EasyInput = {
println(s"STRING JSON $s")
val rawJson = parse(s)
println(s"PARSED JSON $rawJson")
rawJson.extract[EasyInput]
}
}
主文件,工作正常
package validatorbroken
import org.json4s._
import scala.io.Source
object Main extends App {
implicit val formats = DefaultFormats
val easyInputJson: String = Source.fromResource("easy_input.json").mkString
val capturedJson = ProcessInput.captureEasyInput(easyInputJson)
println(s"CAPTURED $capturedJson")
}
而单元测试则不正常
package validatorbroken
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import scala.io.Source
class UnitTests extends AnyFlatSpec with Matchers {
implicit val formats = Main.formats
import ProcessInput._
"captureInput Function" should "obtain an instance of Input" in {
val easyInputJson: String = Source.fromResource("easy_input.json").mkString
val capturedJson = ProcessInput.captureEasyInput(easyInputJson)
println(s"CAPTURED $capturedJson")
}
}
我知道把case类放在包的顶层会有一些问题 但据我所知,我还没有踩到那颗地雷。谁能帮我一把?如果这个问题被证明有一个简单的解决方案,我可能会觉得自己像个白痴,但这已经让我损失了几个小时的工作。
我的堆栈跟踪看起来是这样的。
[info] - should obtain an instance of Input *** FAILED ***
[info] org.json4s.package$MappingException: unknown error
[info] at org.json4s.Extraction$.extract(Extraction.scala:46)
[info] at org.json4s.ExtractableJsonAstNode.extract(ExtractableJsonAstNode.scala:21)
[info] at validatorbroken.ProcessInput$.captureEasyInput(InputToItems.scala:19)
[info] at validatorbroken.UnitTests.$anonfun$new$1(Basic.scala:13)
[info] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
[info] at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
[info] at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
[info] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info] at org.scalatest.Transformer.apply(Transformer.scala:22)
[info] at org.scalatest.Transformer.apply(Transformer.scala:20)
[info] ...
[info] Cause: java.lang.NullPointerException:
[info] at org.json4s.Formats$.customDeserializer(Formats.scala:54)
[info] at org.json4s.Extraction$.customOrElse(Extraction.scala:662)
[info] at org.json4s.Extraction$.extract(Extraction.scala:410)
[info] at org.json4s.Extraction$.extract(Extraction.scala:42)
[info] at org.json4s.ExtractableJsonAstNode.extract(ExtractableJsonAstNode.scala:21)
[info] at validatorbroken.ProcessInput$.captureEasyInput(InputToItems.scala:19)
[info] at validatorbroken.UnitTests.$anonfun$new$1(Basic.scala:13)
[info] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
[info] at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
[info] at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
先谢谢你的帮助,也谢谢你事后的帮助。
...
Cause: java.lang.NullPointerException
...
这是一个很好的指示 初始化问题的顺序.
你使用 import Main.formats
在 ProcessInput
并使用 ProcessInput
在 Main
. 我不明白为什么在Main中可以工作,但在单元测试中却不行,但我建议把定义的 formats
到 ProcessInput
或将其作为隐性论点,以 captureEasyInput
.