2

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"
)
Levi Ramsey
  • 18,884
  • 1
  • 16
  • 30
M.G.
  • 369
  • 1
  • 14
  • Try removing the whole `testSettings` thing and just leaving this `Test / javaOptions += "-Dconfig.resource=/test.conf"` at top level. – Luis Miguel Mejía Suárez May 10 '21 at 18:54
  • I did that but I got the same result, the spec is still reading from application.conf instead of test.conf ... – M.G. May 10 '21 at 19:52
  • What about moving `test.conf` to `src/test/resources/application.conf`? – Luis Miguel Mejía Suárez May 10 '21 at 20:02
  • Yes, it worked. But still my question is what is this line for `Test / javaOptions += "-Dconfig.resource=/test.conf"` ?? Because the spec is reading from application.conf (in `src/test/resources/application.conf`) instead of `test.conf` (`-Dconfig.resource=/test.conf`) – M.G. May 10 '21 at 20:19
  • No in that case that line won't be needed at all, no idea why it didn't work or if it shouldn't have worked at all. – Luis Miguel Mejía Suárez May 10 '21 at 20:24
  • If you're meant to just read the config for other use and not testing the "read config from resource" then I'd recommend you put the config string in your scala source & parse that String. That'll do away with any of classpath stuff & limit your configuration to limited scope (say you have to have different tests referring to slightly different config file) – phongnt May 11 '21 at 11:52

1 Answers1

2

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

yǝsʞǝla
  • 16,272
  • 2
  • 44
  • 65
  • Thank you very much, that clarify how configuration files are being read. Now some things are making sense to me. – M.G. May 11 '21 at 16:32
  • Thank you very much, that clarify how configuration files are being read. Now some things are making sense to me. – M.G. May 11 '21 at 16:32