I have a small program, kind of like a collection ...
# getting-started
j
I have a small program, kind of like a collection of scripts, and I need to have a different config for when I run it normally vs when I run unit tests. Is there a way create a global config so that when I run the script it loads and uses the real config file and when I run the test it loads and uses a test config file? I know every script and test could start by creating a new config, but that seems a bit much 🤔
a
anything is possible! But I suspect that’s not a useful answer. You’ll have to provide more details, show a bit of code, demonstrate a ‘bad’ solution that you want to improve, etc…
snowball hehe 1
j
It’s kind of like how spring (🤮) can easily use different application.yml files Test:
Copy code
internal class CSVDataProviderTest {

    private val csvDataProvider = CSVDataProvider(TestConfig.config.csv.path)

    @Test
    fun getAllData() {
        val data = csvDataProvider.getData("ABC")
        assertEquals(10, data.size)
    }
Config
Copy code
data class Database(val host: String, val port: Int, val user: String, val pass: String)
data class CSV(val path: String)
data class Config(val env: String, val database: Database,  val csv: CSV)

class TestConfig {

    companion object {
        val config = ConfigLoaderBuilder.default()
            .addResourceSource("/test-config.yml")
            .build()
            .loadConfigOrThrow<Config>()
    }

} // Uses hoplite, just parses a file into some data classes
Same thing would apply for the ‘real’ code, a Config class with a new “real-config.yml” file. Would make more sense to me if I just had one Config class (either singleton or normal object blob thinking upside down)
a
so I presume you have some ‘service’ class that you want to test, called
CSVDataProvider
you could add a property with a default value in the constructor?
Copy code
class CSVDataProvider(
  val config: Config = loadConfig() // load using Hoplite
)
then in tests you can manually create a
Config
instance, and pass it into the constructor
Copy code
@Test
fun blah() {
  val testConfig = Config(...)

  val csvDataProvider = CsvDataProvider(config = testConfig)
}
or you could decide on an environment variable that describes the location of the config file
Copy code
MY_PROJECT_CONFIG_FILE_LOCATION=/Users/me/my-project/config.yml
then tell Hoplite to try and load that config, if the property is defined. In tests you could override the environment variable, and set it to a new location. This would be a little more fragile - it might be possible for two tests to accidentally overwrite the environment variable
🙏 1
j
Hmm, yeah some sort of environment variable. Can’t think of any other way to dynamically set the config file name
First way might be best, it’s an extra line of code but it’s very explicit
👍 1