从单元测试中读取配置文件

Reading configuration files from unit tests

我有一个非常简单的项目。

build.sbt:

scalaVersion := "2.13.5"

lazy val testSettings = Seq(
  Test / javaOptions += "-Dconfig.resource=/test.conf"
)

libraryDependencies ++= Seq(
  "org.scalatest" %% "scalatest" % "3.2.3" % Test, 
  "com.typesafe" % "config" % "1.4.1"
)

资源文件夹下的两个配置文件:

application.conf

some-value = "value from application.conf file"

test.conf

some-value = "value from test.conf file"

并且只有 1 个规格测试 class:

一些测试规范:

class SomeTestSpec extends AnyFlatSpec with Matchers {
  val config: Config = ConfigFactory.load()

  "some test" should "read and print from test.conf" in {
    val value = config.getString("some-value")
    println(s"value of some-value = $value")

    value shouldBe "value from test.conf file"
  }
}

当我 运行 测试失败时:

"value from [application].conf file" was not equal to "value from [test].conf file"
ScalaTestFailureLocation: SomeTestSpec at (SomeTestSpec.scala:12)
Expected :"value from [test].conf file"
Actual   :"value from [application].conf file"

为什么规范正在读取文件 application.conf 而不是 test.conf? build.sbt 有什么问题吗?:

lazy val testSettings = Seq(
  Test / javaOptions += "-Dconfig.resource=/test.conf"
)

最佳做法是将 application.conf 放入 src/main/resources/ 以供日常使用,并放入 src/test/resources/ 以供测试。您将在测试中拥有 2 个具有不同值的 conf 文件。如果您不需要为测试更改配置,您可以简单地在 main.

中保留一个 conf 文件

您不必为测试显式地使用 -Dconfig.resource-Dconfig.file 覆盖文件,因为从 class 路径加载资源将按您预期的开箱即用,并且您的测试配置将被使用。 -D选项主要用于运行时提供外部配置或一些复杂的构建场景。

如果使用-Dconfig.resource-Dconfig.file注意路径。 config.resource 只是一个文件名,即 application.conf 将作为资源加载,而 config.file 是绝对或相对文件路径。

如果您正在创建一个库,您可以使用具有默认值的 reference.conf 文件并 application.conf 覆盖它们。这也适用于您的场景,但会更加混乱,因为那不是目的或参考文件。

出于测试目的,只需使用 2 application.conf 个文件。

此外,这里有一些在运行时覆盖配置的选项:

Overriding multiple config values in Typesafe config when using an uberjar to deploy.

Overriding configuration with environment variables in typesafe config

更多信息在这里:https://github.com/lightbend/config#standard-behavior