4

Say I have a Java class Metrics. I defined some extension functions on Metrics in Kotlin

fun Merics.expose(name: String, value: Number) {
 // do something
}

Note that the Java class Metrics also has a method called expose but with different signature.

I created a test where I mocked a metrics objects and call a code path where the extension function expose should be called. But how can I verify that those extension functions are invoked?

I tried to use mockk and mockito-kotlin, none of them seem to know that metrics object has a new function called expose with different signatures.

Rich
  • 1,669
  • 2
  • 19
  • 32

1 Answers1

4

You can not verify that the extension function is called on your mock, as it is not part of that class. The extension function is just a top-level function with a receiver (in your case an instance of Metrics).

But you can still verify that the extension function was called in your code

You can do this using mockkStatic. You are passing the the path of the (generated) extension function. Let's assume you created your Metrics extension function in package org.com. The extension class should get generated in: com.org.MericsExtensionKt.

A test that wants to verify the call to your extension function could look like:

@Test
fun check_metrics_expose_extension_was_called() {
  mockkStatic("com.org.MericsExtensionKt")

  // call your function that is calling Metrics.expose()
  // classUnderTest.someFunction()

  // this verifies a call to the extension function and their parameters
  verify { any<Metrics>().expose(name = any(), value = any()) } 
}
ChristianB
  • 2,452
  • 2
  • 10
  • 22
  • Why are you doing any? I want to use a specific mock object. And when I do use a concrete mock object, it doesn't know this metrics mock object has an `expose` function with this signature. It only knows the `expose` method from the original Java `Metrics` class. – Rich Apr 18 '21 at 15:14
  • Extension functions are static functions in Java. So you can not use a normal mock object calling that static function. The way above is working fine. You can verify any call (incl parameters to the extension (static) function you created. You can use your created mock object of `Metrics` plus the mock of the static call `expose()`. – ChristianB Apr 18 '21 at 16:12
  • Thanks about the static nature of extension functions. What do u mean by "... plus the mock of the static call expose()" ? I do not need to mock the extension function behavior, I wanted to verify it is called. – Rich Apr 18 '21 at 16:32
  • What I meant is that you can mock the orignal `Metrics` class, plus mock the static/extension call and verify it (as it is not part of the actual class/mock). My example above shows how to verify that your extension function was called. I really do not know how else I should demonstrate this scenario. Hope it will help you. – ChristianB Apr 18 '21 at 19:50
  • I slightly adjusted my answer. Hope you can use it. – ChristianB Apr 21 '21 at 20:23
  • Is there a way to call the mockStatic without passing the classPath as a string? – Franz Aug 30 '22 at 16:08