https://kotlinlang.org logo
Title
d

dave08

12/03/2020, 5:07 PM
If I'm making an abstract base class for tests that need a testcontainers db connection (in Micronaut Test), is there some kind of generic test type I can use, and then just use whichever of the styles in the actual tests inherited from it?
Something like what's over here: https://akobor.me/posts/using-testcontainers-with-micronaut-and-kotest but without being tied down to a specific style.
s

sam

12/03/2020, 8:15 PM
What you need is a kind of uber style.
Doesnt exist unfortunately
t

thanksforallthefish

12/04/2020, 6:52 AM
disclaimer first, we don’t use kotest testcontainers library because we started with testcontainers before I found about the library (and you know, as long as it works - and it is not too ugly) and we use spring boot, but we did something like
class ProjectConfig : AbstractProjectConfig() {
  override fun listeners() = listOf(PostgresListener, SpringListener, object : TestListener {
    override suspend fun afterTest(testCase: TestCase, result: TestResult) {
      clearAllMocks()
    }
  })
}

object PostgresListener : ProjectListener {
  private val withNetworkAliases = PostgreSQLContainerProvider().newInstance("10")
    .withNetwork(Network.SHARED)
    .withNetworkAliases("db")

  override suspend fun beforeProject() {
    withNetworkAliases.start()
    System.setProperty("spring.datasource.url", "jdbc:postgresql://${withNetworkAliases.connectionString()}")
    System.setProperty("spring.datasource.username", withNetworkAliases.getUsername())
    System.setProperty("spring.datasource.password", withNetworkAliases.getPassword())
    System.setProperty("spring.flyway.schemas", withNetworkAliases.getDatabaseName())
  }

  override suspend fun afterProject() {
    withNetworkAliases.stop() //probably not needed because of ryuk
  }

  private fun JdbcDatabaseContainer<*>.connectionString() = "${getHost()}:${getFirstMappedPort()}/${getDatabaseName()}"

  override val name = "PostgresListener"
}
then db tests can be regular
SpringBootTest
(or test slice if only the db is needed) since the configuration properties are set. I don’t know micronaut (it might or might not be explored in the service we need to implement), but something like this might work for you as well
d

dave08

12/04/2020, 8:47 AM
You're probably right @thanksforallthefish, in this case a listener could do the trick. But we find ourselves injecting a bunch of deps on the test level for, say, integration testing, that might not be needed in other tests. There is a way to register listeners on the class level, but having a base class might be a bit clearer...