2014-05-09 21 views
6

使用的ScriptEngine下面的测试应该通过,但是它没有如何ScalaTest

class EngineTest extends FunSuite { 

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

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

+0

所做的测试通过在IDE而不是从外壳SBT。不知道有什么不同。 – jonbros

+0

类路径很可能是问题 – aepurniet

+0

http://stackoverflow.com/q/10054252/1296806对于rhino支持的distro-dependent。 –

回答

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 = [email protected] 

scala> new ScriptEngineManager().getEngineByName("rhino") 
res1: javax.script.ScriptEngine = [email protected] 

scala> new ScriptEngineManager().getEngineFactories 
res2: java.util.List[javax.script.ScriptEngineFactory] = [[email protected], [email protected]] 

等待,你问关于测试情境 -

嘛,以前我迷失在解码更SBT的兴趣,加入到libraryDependencies:

"org.scala-lang" % "scala-compiler" % scalaVersion.value % "test", 

使定位斯卡拉脚本引擎:

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

毫无疑问,有一个简单的方法来添加运行时:full-classpath to test:f直接的类路径。因为它是简单的构建工具,对吗?

对于犀牛关于Java 8,注意位置:

> 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: [[email protected]] 
[info] Passed: Total 10, Failed 0, Errors 0, Passed 10 

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

而且I guess it's still considered black art

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

fork in Test := true 
+0

我只是猜测:'>设置(测试中的fullClasspath)++ =(运行时的fullClasspath).value',但这些只是代价。 –

+0

我想我在这里学到了一些关于sbt的知识。非常感谢! – jonbros

4

你需要在一个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) 
    } 
} 

这两项测试都通过了对我来说:

[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.