[Different Database for Testing] TL;DR : if you k...
# server
b
[Different Database for Testing] TL;DR : if you know how to properly use different KMongo databases when testing pieces of code that statically reference a database variable, you might just be my saviour Hi everyone, I apologise in advance if this message has nothing to do here, please do say so if it is the case. I'm working on a web-app with Kotlin MPP which I am discovering. I am starting to want to develop a test base to have healthier code practices, but I ran into a problem when wanting to test my KMongo database accesses for the Kotlin/JVM part. My controller (and test class) access MyService 's methods which are stored in its companion object
Copy code
val myCollection = database.getCollection<Object>()
class MyService {
    companion object {
        suspend fun myMethod(){
            myCollection.doSomething()
        }
    }
}
The issue is that the
database
object called here is imported from my Server class where it is imported as such:
Copy code
val client = KMongo.createClient().coroutine
val database = client.getDatabase("debug_name")
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
Now, this worked perfectly until I needed to test it (I know I should've started by the tests, my bad) The issue is that, as it is, when my test class calls
MyService.myMethod()
, the collection used is the "debug_name". I have instantiated another database in the
@BeforeClass
method from my test class, but I can't figure out how to use it. My different ideas so far have consisted of : • using a constructor for the Service class with the database to use, which I know is not a good solution • detecting the type of build running to pass a different parameter to the
getDatabase()
method (maybe via environment variables?), but I feel like this would not be optimal at all and kind of go against the idea behind testing philosophy, as it sould still be using the
database
variable stored in the
Server
file instead of a controlled test-environment database I am absolutely unsure of how to go about this and nothing I have tried has even started to work a tiny bit. If you have insights on how to properly do this, I'd be super grateful ! A wannabe-programmer
e
• using a constructor for the Service class with the database to use, which I know is not a good solution
Why do you say that? It's called dependency injection and it's a super common pattern to achieve what you want 🙂
💯 4
👀 1
Can you elaborate a bit on what you want to achieve in
MyService
btw? It sounds like you might not need a class at all even.. perhaps just an extension method on
Iterable<Object>
for instance
b
So my take was that in my very limited experience developping websites, I have used Java and Springboot, which uses "@Profile" to distinguish testing, dev and production. Then, the "@Autowire" would know which database to use. Concerning
MyService
it's just a generic representation of my different services. In the structure of my back-end, I have controllers which contain extension methods for
Route
to control the ktor routing, then these call the corresponding
Service
method that handles all of the logic, most times having to call a
Repository
, in which the
database
really is (I didn't want to over-complicate it by getting into deep details in my original message) For example, the backend receives a get request to
"/myObject/{id}"
. The controller then calls the
MyService.getObject(id)
method (stored in companion object of the service), which in turn calls the repository's
MyRepository.findObject(id)
method, in the companion object of the repository class I guess there might be a more idiomatic way to do this, to be honest I am simply trying to have a somewhat structured and organised project However, thanks for your quick reply, I will try implementing that correctly !
Well, here's to working in the morning VS in the afternoon: I have found my solution. Turns out, by changing my
database
variable from
val
to
var
I could just simply set it to be the test database in my
@BeforeClass
method and voila Thank you for your time and answers though