I have a very simply project.
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"
)
Two configuration files under resources folder:
application.conf
some-value = "value from application.conf file"
test.conf
some-value = "value from test.conf file"
And only 1 spec test class:
SomeTestSpec:
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"
}
}
When I run the test if fails:
"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"
Why the spec is reading the file application.conf
instead of test.conf
? Is something wrong in the build.sbt?:
lazy val testSettings = Seq(
Test / javaOptions += "-Dconfig.resource=/test.conf"
)
The best practice is to place application.conf
into src/main/resources/
for regular use and into src/test/resources/
for testing. You'll have 2 conf files with different values in test. If you don't need to change config for test you can simply keep one conf file in main
.
You don't have to override the file explicitly with -Dconfig.resource
or -Dconfig.file
for your tests because loading resources from class path will work as you expect out of the box and your test config will be used. -D
option is mostly used at runtime to provide external configuration or in some complex build scenarios.
If you use -Dconfig.resource
or -Dconfig.file
pay attention to the path. config.resource
is just a filename, i.e. application.conf
which will be loaded as resource while config.file
is an absolute or relative file path.
If you are making a library you can get fancy with reference.conf
file having default values and application.conf
overriding them. This could also work in your scenario but would be more confusing because that's not the purpose or reference file.
For the purposes of testing just use 2 application.conf
files.
Additionally, here are some options to override config at runtime:
Overriding multiple config values in Typesafe config when using an uberjar to deploy.
Overriding configuration with environment variables in typesafe config
Scala environment ${USER} in application.conf
More info here: https://github.com/lightbend/config#standard-behavior