Search code examples
kotlindependency-injectiondelegatescomposition

How do I inject a dependency into an interface delegate in Kotlin?


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?


Solution

  • Why not just use constructor dependency injection?

    class MyThingie(
        dep: ThingieWithCreatedTS = ThingieCreatedAtNow
    ) : ThingieWithCreatedTS by dep {}
    

    Now you can provide fake ThingieWithCreatedTS dependency in tests