I'm trying to figure out how to inject a dependency into an interface delegate in Kotlin. I have a class:
class MyThingie {}
And I want to add a field created_time
to this class that might also be added to other classes. So I can create an interface and an instance implementation of this interface, and then add that delegation into the class definition:
interface ThingieWithCreatedTS {
val created_ts: Long
}
object ThingieCreatedAtNow : ThingieWithCreatedTS {
override val created_ts: Long = System.currentTimeMillis()
}
class MyThingie : ThingieWithCreatedTS by ThingieCreatedAtNow {}
This is great. Now I can call created_ts
on any instance of MyThingie
and get the timestamp it was created. However, this is now hard to test.
I don't really want to be trying to mock System
, and I understand the correct pattern for this is to inject some sort of Clock instance into whatever needs to know the current time. That way, I can provide a RealClock in the code, and under test I can provide a FakeClock (that I can control the output from).
It's not clear how I can do this on this pattern. How can I pass an implementation instance into a delegate?
Why not just use constructor dependency injection?
class MyThingie(
dep: ThingieWithCreatedTS = ThingieCreatedAtNow
) : ThingieWithCreatedTS by dep {}
Now you can provide fake ThingieWithCreatedTS
dependency in tests