How to mock Kotlin extension function using Mockito or PowerMock in tests? Since they are resolved statically should they be tested as static method calls or as non static?
In Android, there are a lot of frameworks used for mocking in unit testing, such as PowerMock, Mockito, EasyMock, etc. MockK is definitely a better alternative to other mocking frameworks for Kotlin, the official development language for Android. Its main philosophy is first-class support for Kotlin features.
Mockito has been around since the early days of Android development and eventually became the de-facto mocking library for writing unit tests. Mockito and Mockk are written in Java and Kotlin, respectively, and since Kotlin and Java are interoperable, they can exist within the same project.
Mockk is a mocking framework built for Kotlin. Like Mockito, Mockk allows you to create and stub objects within your test code. Mocking objects allows you to test in isolation other objects. Any dependency of the object under test can be mocked to provide fixed conditions, thus ensuring specific and stable tests.
Inside the verification block (between the opening curly bracket { and closing curly bracket } ), you write the method you want to verify. { navigator. navigateTo("Park") } tells MockK to check if the navigateTo method on the navigator object was called with the argument "Park" .
I think MockK can help you.
It supports mocking extension functions too.
You can use it to mock object-wide extensions:
data class Obj(val value: Int)
class Ext {
fun Obj.extensionFunc() = value + 5
}
with(mockk<Ext>()) {
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
}
If you extension is a module-wide, meaning that it is declared in a file (not inside class
), you should mock it in this way:
data class Obj(val value: Int)
// declared in File.kt ("pkg" package)
fun Obj.extensionFunc() = value + 5
mockkStatic("pkg.FileKt")
every {
Obj(5).extensionFunc()
} returns 11
assertEquals(11, Obj(5).extensionFunc())
verify {
Obj(5).extensionFunc()
}
By adding mockkStatic("pkg.FileKt")
line with the name of a package and file where extension is declared (pkg.File.kt
in the example).
More info can be found here: web site and github
First of all, Mockito knows nothing Kotlin specific language constructs. In the end, Mockito will have a look into the byte code. Mockito is only able to understand what it finds there and what looks like a Java language construct.
Meaning: to be really sure, you might want to use javap to deassemble the compiled classfiles to identify the exact names/signatures of the methods you want to mock.
And obviously: when that method is static, you have to user PowerMock, or JMockit; if not, you should prefer to with Mockito.
From a java point of view, you simply avoid mocking static stuff; but of course, things get really interesting, now that different languages with different ideas/concepts come together.
Instance extension functions can be stubbed and verified like this with the help of mockito-kotlin:
data class Bar(thing: Int)
class Foo {
fun Bar.bla(anotherThing: Int): Int { ... }
}
val bar = Bar(thing = 1)
val foo = mock<Foo>()
with(foo) {
whenever(any<Bar>().bla(any()).doReturn(3)
}
verify(foo).apply {
bar.bla(anotherThing = 2)
}
I use mockk library.
For extension file write java name, like this:
@file:JvmName(name = "ExtensionUtils")
package myproject.extension
...
And for fast codding I created file with different extension mocks:
object FastMock {
fun extension() = mockkStatic("myproject.extension.ExtensionUtils")
fun listExtension() = mockkStatic("myproject.extension.ListExtensionUtils")
}
In test call this:
FastMock.listExtension()
every { itemList.move(from, to) } returns Unit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With