2015-12-01 53 views
3

我有一个需要环境变量才能正确运行一些代码。但是当我运行我的单元测试时,除非我专门在终端中输出变量,否则一旦它达到该点就会弹出。我正在使用Scala和sbt。我的代码确实是这样的:如何测试需要环境变量的代码?

class something() { 

    val envVar = sys.env("ENVIRONMENT_VARIABLE") 

    println(envVar) 

} 

我怎么能嘲笑这在我的单元测试,以便每当sys.env(“ENVIRONMENT_VARIABLE”)被调用,它返回一个字符串或类似的东西?

+3

我包裹在单独的服务检索ENV变量和测试 – xersiee

+0

时,如果你不能完成现有的代码嘲笑它,你可以改变UnmodifiableMap System.getenv()进行测试。 –

回答

1

理想的情况下,环境访问应该被改写以安全的方式来检索数据。无论是用默认值...

scala> scala.util.Properties.envOrElse("SESSION", "unknown") 
res70: String = Lubuntu 

scala> scala.util.Properties.envOrElse("SECTION", "unknown") 
res71: String = unknown 

...或作为选项...

scala> scala.util.Properties.envOrNone("SESSION") 
res72: Option[String] = Some(Lubuntu) 

scala> scala.util.Properties.envOrNone("SECTION") 
res73: Option[String] = None 

...或两者[见envOrSome()]。

我不知道有什么办法让它看起来像任何/所有随机ENV瓦尔设置不运行测试之前实际设置它们。

+0

静默使用的是假值(“未知”),而不是抛出一个异常似乎并不安全。 – stackexchanger

+0

@stackexchanger,在这种情况下“安全地”,简单的说:除非设计规定不抛出异常。这完全取决于设计要求。如果设计不允许默认的(不是“假”)值,则使用Option []选项。 – jwvh

-1

你不应该在单元测试进行测试。

只需提取出来

class F(val param: String) { 
    ... 
} 

在你督促你的代码做

new Foo(sys.env("ENVIRONMENT_VARIABLE")) 
2

如果你不能完成现有的代码,你可以改变UnmodifiableMap System.getenv()进行测试。

def setEnv(key: String, value: String) = { 
    val field = System.getenv().getClass.getDeclaredField("m") 
    field.setAccessible(true) 
    val map = field.get(System.getenv()).asInstanceOf[java.util.Map[java.lang.String, java.lang.String]] 
    map.put(key, value) 
} 

setEnv("ENVIRONMENT_VARIABLE", "TEST_VALUE1") 

如果您需要测试控制台输出,您可以使用单独的PrintStream。 你也可以实现你自己的PrintStream。

val baos = new java.io.ByteArrayOutputStream 
val ps = new java.io.PrintStream(baos) 
Console.withOut(ps)(
    // your test code 
    println(sys.env("ENVIRONMENT_VARIABLE")) 
) 

// Get output and verify 
val output: String = baos.toString(StandardCharsets.UTF_8.toString) 
println("Test Output: [%s]".format(output)) 
assert(output.contains("TEST_VALUE1"))