Search code examples
kotlinkotlin-extension

unit testing extension function and mocking the other methods of the class


I am writing an extension function adding some retry capabilities to AmazonKinesis.putRecords. In my extension method i do some logic and some calls to the original putRecords method:

fun AmazonKinesis.putRecordsWithRetry(records: List<PutRecordsRequestEntry>, streamName: String) {
    //...
    val putRecordResult = this.putRecords(PutRecordsRequest().withStreamName(streamName).withRecords(records))
   //...
}

From a unit test point of view I am finding it hard to see how I should mock the call to this.putRecords

I am using com.nhaarman.mockitokotlin2.*

val successfulRequest = PutRecordsResultEntry().withErrorCode(null);

class KinesisExtensionTest : StringSpec({
    val testRecords = ArrayList<PutRecordsRequestEntry>()
    testRecords.add(PutRecordsRequestEntry().withPartitionKey("iAmABunny").withData(ByteBuffer.wrap("aaa".toByteArray()))
    )

    val kinesis = mock<AmazonKinesis>{
        on { putRecordsWithRetry(testRecords, "/dev/null") }.thenCallRealMethod()
        on { putRecords(any()) }.thenReturn(PutRecordsResult().withRecords(listOf(successfulRequest, successfulRequest)))
    }


    "can write a record" {
        kinesis.putRecordsWithRetry(testRecords, "/dev/null")
        verify(kinesis).putRecord(any())
    }
})

The putRecordResult is always null


Solution

  • The extension function AmazonKinesis.putRecordsWithRetry will be compiled to a static function under the hood, and Mockito doesn't support static method mocking yet.

    Therefore Mockito may not know the stubbing information at the verification step and thus the default null value is produced.