如何在ScalaTest中使用ScriptEngine

jon*_*ros 7 scala scalatest java-8 nashorn

以下测试应该通过,但事实并非如此

class EngineTest extends FunSuite {

  test("engine should not be null") {
    val manager: ScriptEngineManager = new ScriptEngineManager
    val engine: ScriptEngine = manager.getEngineByName("nashorn")
    assert(engine != null)
  }
}
Run Code Online (Sandbox Code Playgroud)

manager.getEngineFactories()似乎是空的.为什么?如何初始化上下文?

tpu*_*der 5

您需要将ClassLoader显式传递给ScriptEngineManager构造函数。如果不这样做,那么Thread.currentThread().getContextClassLoader()在SBT下运行时,它将使用设置为怪异的值。我们只是传入null代码以使其正常工作。您也可以传递getClass.getClassLoader

class EngineTest extends FunSuite {
  test("engine should not be null - null classloader") {
    val manager: ScriptEngineManager = new ScriptEngineManager(null)
    val engine: ScriptEngine = manager.getEngineByName("nashorn")
    assert(engine != null)
  }

  test("engine should not be null - getClass.getClassLoader classloader") {
    val manager: ScriptEngineManager = new ScriptEngineManager(getClass.getClassLoader)
    val engine: ScriptEngine = manager.getEngineByName("nashorn")
    assert(engine != null)
  }
}
Run Code Online (Sandbox Code Playgroud)

这些测试对我来说都是通过的:

[info] EngineTest:
[info] - engine should not be null - null classloader
[info] - engine should not be null - getClass.getClassLoader classloader
[info] Run completed in 186 milliseconds.
[info] Total number of tests run: 2
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
Run Code Online (Sandbox Code Playgroud)


som*_*ytt 3

您使用什么版本?这是 sbt .13。

> console
[info] Starting scala interpreter...
[info] 
Welcome to Scala version 2.11.0 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import javax.script._
import javax.script._

scala> new ScriptEngineManager().getEngineByName("scala")
res0: javax.script.ScriptEngine = scala.tools.nsc.interpreter.IMain@7078c799

scala> new ScriptEngineManager().getEngineByName("rhino")
res1: javax.script.ScriptEngine = com.sun.script.javascript.RhinoScriptEngine@5c854934

scala> new ScriptEngineManager().getEngineFactories
res2: java.util.List[javax.script.ScriptEngineFactory] = [com.sun.script.javascript.RhinoScriptEngineFactory@454ee4c0, scala.tools.nsc.interpreter.IMain$Factory@354e3bce]
Run Code Online (Sandbox Code Playgroud)

等等,你问的是测试背景——

好吧,在我对解码更多 sbt 失去兴趣之前,添加到库依赖项:

"org.scala-lang" % "scala-compiler" % scalaVersion.value % "test",
Run Code Online (Sandbox Code Playgroud)

允许定位 Scala 脚本引擎:

  @Test def engines: Unit = {
    import javax.script._
    val all = new ScriptEngineManager().getEngineFactories
    Console println s"Found ${all.size}: $all"
    assert(all.size > 0)
  }
Run Code Online (Sandbox Code Playgroud)

毫无疑问,有一种简单的方法可以直接将runtime:full-classpath添加到test:full-classpath。因为它是简单的构建工具,对吧?

对于 Java 8 上的 Nashorn,请记下位置:

> set fullClasspath in Test += Attributed.blank(file(s"${util.Properties.javaHome}/lib/ext/nashorn.jar"))
[info] Defining test:fullClasspath
[info] The new value will be used by test:console, test:executeTests and 5 others.
[info]  Run `last` for details.
[info] Reapplying settings...
[info] Set current project to goofy (in build file:/home/apm/goofy/)
> test
Found 1: [jdk.nashorn.api.scripting.NashornScriptEngineFactory@7fa2239d]
[info] Passed: Total 10, Failed 0, Errors 0, Passed 10
Run Code Online (Sandbox Code Playgroud)

更新: https: //github.com/sbt/sbt/issues/1214

另外我猜它仍然被认为是黑艺术

// Somehow required to get a js engine in tests (https://github.com/sbt/sbt/issues/1214)

fork in Test := true
Run Code Online (Sandbox Code Playgroud)