Published on

Using Apply to Avoid var and nullability in Kotlin

Authors

I was busy writing a test today in Kotlin and one of the things I was testing had a properties object. This object was in the form of a Java bean where the Spring Environment gets injected in to wire the properties in the class differently depending on the environment it is being run for (i.e. dev, test or prod). To get around this in the test and the avoid the need to make this a full blown Spring integration test I mocked this property class:

private val someProperties = Mockito.mock(SomeProperties::class.java)
private var yourClient: YourClient? = null

@Before
fun setUp() {
    `when`<String>(yourProperties.url).thenReturn("http://your.end.point:9000/your/path")

    yourClient = YourClient(yourProperties)
}

The problem now is that:

  1. My client has to be made a var and nullable
  2. I need to have a setup method to mock my object
  3. I need to use the setup method to construct my client and constructor inject the mock
  4. I need to use yourClient!!.methodBeingTested() whenever I call this which is annoying
  5. This feels very boilerplaty and unnecessarily heavy

I figured there had to be a better way. I ended up using Kotlin's apply function on the mock and mocking the properties class inline. Apply is cool as I do not need to specify this or it before the property I want, I can access the property classes fields directly which reads better. This allowed me to clean up the code significantly by deleting the setup method, initializing yourClient inline, making it a val and removing the need for it to be nullable:

private val someProperties: SomeProperties = Mockito.mock(SomeProperties::class.java).apply {
        `when`<String>(url).thenReturn("http://your.end.point:9000/your/path")
}

private val yourClient: YourClient = YourClient(someProperties)

You need to specify the type of someProperties explicitly otherwise Kotlin is unable to infer the type of the variable.