If we want to test an extension function on a type, we can create an instance of this type, call the function and check the returned value. But what about testing extension functions defined inside classes?
abstract class AbstractClass<T> {
fun doStuff(): T = "Hello".foo()
abstract fun String.foo(): T
}
class SubClass1: AbstractClass<Int>() {
override fun String.foo(): Int = 1
}
class SubClass2: AbstractClass<Boolean>() {
override fun String.foo(): Boolean = true
}
How do we test the logic of the methods foo()
in classes SubClass1
and SubClass2
? Is it even possible?
I know I can change the design to test it. Two possibilities have occurred to me:
Don't use extension functions. ¯\_(ツ)_/¯
abstract class AbstractClass<T> {
fun doStuff(): T = foo("Hello")
abstract fun foo(string: String): T
}
class SubClass1: AbstractClass<Int>() {
override fun foo(string: String): Int = 1
}
Then we can create an object SubClass1
, call foo()
and check the returned value.
Create additional extension functions with internal
visibility just to test the logic.
class SubClass1: AbstractClass<Int>() {
override fun String.foo(): Int = internalFoo()
}
internal fun String.internalFoo(): Int = 1
Then we can create an object String
, call internalFoo()
and check the returned value. However, I don't like this solution because we could change the body of override fun String.foo(): Int
and our test would pass.
So, is it possible to test extension functions inside classes? If not, how would you change your design in order to test their logic?
An extension function can go anywhere a regular function can. It may be top-level (equivalent to java static), in a companion object (act like static but not equivalent to java static), or as a member of a class (not static at all).
Example of extension function declaration and its useisExcellent() and call it from the main() function. The declare Student. isExcellent() function is known as extension function, where Student class is known as receiver type. The above example only demonstrates about how to declare an extension function.
Extension functions are a cool Kotlin feature that help you develop Android apps. They provide the ability to add new functionality to classes without having to inherit from them or to use design patterns like Decorator.
In particular, Kotlin extensions let you add functions to a class that you cannot modify. By using them, you will be able to call these new functions as if they were part of the original class. Similarly, you can use this mechanism to add new properties to existing classes. You can also extend Kotlin companion objects.
Since tests should be written from the client's perspective, I'm not sure it would be a valid test. But I did come up with one way to test it.
@Test
fun `test extension function`() {
var int = 0
SubClass1().apply {
int = "blah".foo()
}
assertThat(int, `is`(1))
}
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