Home > other >  sbt how to access base directory of project in scala code
sbt how to access base directory of project in scala code

Time:12-16

I have been given a code which was created by a vendor and seems like their engineer did a lot of hardcoding in the unit tests. I have a unit test for a function which outputs the full absolute path of report generated as part of the code as a string. currently the unit test/assertion that fails looks like

val reportPath  = obj.getReportPath()
assert(reportPath.equals("file:/Users/khalid.mahmood/ReportingModule/target/report.csv")

where ReportingModule is the name of the project.

The code logic is fine as for me the value of the reportPath variable comes out to be:

file:/Users/vikas.saxena/coding_dir/ReportingModule/target/report.csv

Since I have the project cloned in a subdirectory called coding_dir in my home directory so the logic looks fine to me.

I want to modify the assertion to ensure that the code pics up the base directory of project by itself and on googling I found that sbt has base as the equivalent of project.baseDir (from maven) from this link

However the following code changes haven't worked out for me

assert(reportPath.equals(s"""$base"""   "/target/report.csv")

Can I get some pointers on how to get this right.

CodePudding user response:

If you're using ScalaTest, you can use a ConfigMap to do it.

First you need to tell the ScalaTest Runner to add the path to the ConfigMap. This can be done in your .sbt file like so:

Test / testOptions  = Tests.Argument(
  TestFrameworks.ScalaTest, s"-DmyParameter=${baseDirectory.value}")

(note that it doesn't have to be baseDirectory.value, many other sbt settings will work. I would suggest target.value for your specific use case).

In the test itself, you then need to access the value from the ConfigMap. The easiest way to do this is to use a Fixture Suite (such as FixtureAnyFunSuite) and mix in the ConfigMapFixture trait:

import org.scalatest.funsuite.FixtureAnyFunSuite
import org.scalatest.fixture.ConfigMapFixture

class ExampleTest extends FixtureAnyFunSuite with ConfigMapFixture {
  test("example") { configMap =>
    val myParameter = configMap.getRequired[String]("myParameter")
    // actual test logic goes here
    succeed
  }
}

There are of course other ways to solve the problem. For instance, you can also simply get the current working directory (cwd) and work from there. However the downside to that is that in multi-module builds, the cwd will be different depending on whether the Test / fork setting in sbt is true or false. So to make your code robust against these sorts of eventualities, I recommend sticking with the ConfigMap way.

  • Related