2014-05-09 47 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.