Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何测试需要环境变量的代码?_Scala_Unit Testing_Environment Variables - Fatal编程技术网

Scala 如何测试需要环境变量的代码?

Scala 如何测试需要环境变量的代码?,scala,unit-testing,environment-variables,Scala,Unit Testing,Environment Variables,我有一些代码需要一个环境变量才能正确运行。但是,当我运行单元测试时,除非我在终端中专门导出变量,否则一旦达到该点,它就会爆炸。我正在使用Scala和sbt。我的代码执行如下操作: class something() { val envVar = sys.env("ENVIRONMENT_VARIABLE") println(envVar) } 我如何在单元测试中模拟它,以便无论何时调用sys.env(“环境变量”),它都会返回字符串或类似的内容?理想情况下,应该重写环境访问以安全

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

class something() {

  val envVar = sys.env("ENVIRONMENT_VARIABLE")

  println(envVar)

}

我如何在单元测试中模拟它,以便无论何时调用sys.env(“环境变量”),它都会返回字符串或类似的内容?

理想情况下,应该重写环境访问以安全地检索数据。或者使用默认值

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()
]


我不知道有什么方法可以让它看起来像任何/所有随机环境变量都是在运行测试之前实际设置的。

您不应该在单元测试中测试它

把它取出来

class F(val param: String) {
  ...
}
在prod代码中,您可以

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

如果无法包装现有代码,则可以更改测试的不可修改映射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"))

我会将配置封装在一个不公开实现的装置中,可能是一个类ConfigValue

我将把实现放在ConfigValueInVvar扩展ConfigValue类中

这允许我测试依赖于ConfigValue的代码,而无需设置或清除环境变量

它还允许我测试将值存储在环境变量中作为单独特性的基本实现

它还允许我将配置存储在数据库、文件或任何其他文件中,而无需更改业务逻辑

我选择应用层中的实现。 我将环境变量逻辑放在一个支持域中。
我将业务逻辑和特性/接口放在核心域中。

我将在单独的服务中包装检索环境变量,并在测试时模拟它。如果无法包装现有代码,则可以更改不可修改的Map System.getenv()以进行测试。无声地使用假值(“未知”)而不是引发异常似乎并不安全。@StackExchange,在本文中,“安全方式”的意思是:除非在设计中指定,否则不会引发异常。这完全取决于设计要求。如果设计不允许约定的默认值(不是“假”),则使用
选项[]
选项。
setEnv
非常有用。谢谢在我的单元测试中,我可以在创建我的对象之前调用它,并验证新值是否被拾取。FOLLOWUP:Hmm。即使该方法声称有效,调用它似乎不会改变环境。唉。需要更多的研究。