Hello. I have a ktor route that calls a simple bus...
# server
g
Hello. I have a ktor route that calls a simple business function to process data. The Route is responsible for receiving data from the body and passing it to the business function, and for formatting the returned values. Like so:
Copy code
get("/some/uri") {
  val data = call.receive<SomeType>()
  val result = doBusinessStuffWith(data)
  call.respond(result.doSomeFormatting()
}
And the business function is defined somewhere else:
Copy code
fun doBusinessStuffWith(data: SomeType): SomeReturnType {
...
}
Is there a way to test the controller in isolation by mocking the business function
doBusinessStuffWith
? In Javascript, you can mock any function call with
jest
. I assume, it is not that easy in kotlin, but is there a nice way? Thank you for your ideas …
d
You can, of course use a mock. Suggest that you maybe think about structuring your app using Hexagonal Architecture to split your adapter logic from your business logic.
s
You can indeed mock top level functions with something like #mockk. I don’t find mocking top level functions in Kotlin quite as clean as jest, but it’s not bad. The downside is it stops you from running tests in parallel.
d
I propose to move the
doBusinessStuffWith(...)
to a dedicated class. This would not only make testing simpler (you can then simply mock that class and the method call), but it would also clarify the responsibilities of the two classes: One for routing and request/response handling, one for doing logic.
g
@Dominik Sandjaja That’s how you would do it with spring boot. What I like at ktor is that you don’t have to write classes but can work functional. The separation can come from different files that use private and public funtions but no classes. @Sam That sound interesting. I will try that, thank you. @dave Could be an interesting approach. But I always find the “stiching together” tiresome and data has to flow up- and downward longer ways.
Some thought that I had: Can you use Koin to inject a function? That could solve the problem and be still quite functional. I want to use Koin in the backend anyway, but am pretty new to that framework
d
We use Koin and we use a hexagonal approach, exactly to split the responsibilities: Input/Output into a system is e.g. the HTTP route, the actual business logic is in a separate class. Yes, it would be the same in Spring, but that does not necessarily mean that it's a bad thing 🙂
d
If you don't use a DI framework, you could inject a function into your controller. Probably doesn't work with the magic though 😂
👍 1
g
Thank you all. I will take a look.
d
Copy code
fun myController(fn: (String) -> DomainThing)