Kotlin: How to verify an extension function is called on a mock - kotlin

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.

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()) }
}

Related

How to enforce the method signature of a function at compile time

I have a usecase where through reflection I invoke specific functions that are annotated uniquely.
Here below MyClass and functionName have already been identified due to their annotation and are getting invoked.
MyClass.javaClass?.kotlin?.memberProperties?.find { function ->
function == functionName
}?.call(MyClass, params)
My concern is since these functions are written separately how do I ensure that these functions are always of the expected signature i.e. accepts a specific set of params that I define, because if not they would end up failing at runtime.
Is there a way to enforce a method signature contract through annotation?
The current approach I could come up with is to define a functional interface
fun interface MyHandler{ handle(params) }
and then create properties(rather than functions) that necessarily implement this functional interface (I'm hoping I will be able to filter properties that implement an interface)
var handler1 = MyHandler {params-> println("BL first $params")}
var handler2 = MyHandler {params-> println("BL second $params")}
But I do not know how to invoke such properties through reflection.

Why/How does this extension function work? How to call it without `with`?

While taking the "Kotlin for Java Developers" Coursera course, I came across this construction, where an extension function for a contained instance seems to have access to the containing class' private fields. Note how the Data class is implemented outside of Container and does not have access to Container's fields, but the Data.printMe() extension function can access Container's private containerVal member:
data class Data (val data: String)
class Container (private val containerVal: String, val data: Data){
fun Data.printMe() {
println("data: $data - in container: ${this#Container.containerVal}")
}
}
fun main() {
val c = Container("mycontainer", Data("mydata"))
// Can I call Data.printMe without using `with`?
// val d = c.data.printMe();
with (c) {
// Prints: data: mydata - in container: mycontainer
data.printMe();
}
}
Pretty cool that Data.printMe can access Container's private members. The with(c) is apparently what allows that. I can see lots of use cases for this, just like how in the course example extension functions for a game's Cells can access the containing Board without the Cell class itself being polluted by and tightly coupled with Board.
Does this "approach" have a name? And is there a syntax to call c.data.printMe "directly" without using with? The with documentation doesn't mention this use case.
The printMe() method has two receivers: the dispatch receiver and the extension receiver. The dispatch receiver is the instance of the class in which the extension is declared, and the extension receiver is the instance of the receiver type of the extension method. You are accessing contaiverVal in the context of a Container instance (dispatch receiver), not a Data instance (extension receiver).
If you try to do the opposite and access a private property of the Data class inside the printMe(), you will get a compiler error.
when you define an extension function as a member of a class, it is only usable in the context that class. You can access it inside the class or using a scope function where the context object is available as a lambda receiver (this). Those functions are run, with and apply.

extension function is virtual to dispatch reciever?

In kotlin Declaraing extensions as members, what does it mean "the dispatch of such functions is virtual with regard to the dispatch receiver type, but static with regard to the extension receiver type."
Is this mean that "the extension function doesn't follows its reciever's class type. It follows parameter type(?in this code call method parameter)."
please give your warmhearted and generous advice
open class Base { }
class Derived : Base() { }
open class BaseCaller {
open fun Base.printFunctionInfo() {
println("Base extension function in BaseCaller")
}
open fun Derived.printFunctionInfo() {
println("Derived extension function in BaseCaller")
}
fun call(b: Base) {
b.printFunctionInfo() // call the extension function
}
}
class DerivedCaller: BaseCaller() {
override fun Base.printFunctionInfo() {
println("Base extension function in DerivedCaller")
}
override fun Derived.printFunctionInfo() {
println("Derived extension function in DerivedCaller")
}
}
fun main() {
BaseCaller().call(Base()) // "Base extension function in BaseCaller"
DerivedCaller().call(Base()) // "Base extension function in DerivedCaller" - dispatch receiver is resolved virtually
DerivedCaller().call(Derived()) // "Base extension function in DerivedCaller" - extension receiver is resolved statically
}
Since you have linked the documentation, I take it that you have read the following part
The instance of the class in which the extension is declared is called
dispatch receiver, and the instance of the receiver type of the extension method is called extension receiver.
After you have understood the above terminology, you need to understand following points
If you don't know about virtual methods read this
Extensions are resolved statically. Consider the following code block
fun call(b: Base) {
// This will always call extension function defined on the Base class
// even if you pass an object of Derived class
b.printFunctionInfo() // call the extension function
}
// This calls the printFunctionInfo defined on the Base, even though we pass Derived
DerivedCaller().call(Derived())
Now to your question
the dispatch of such functions is virtual with regard to the dispatch
receiver type, but static with regard to the extension receiver type.
With the Extensions are resolved statically point we have established that no matter which object you pass (Base or Derived) the call function will always invoke an extension function defined on the Base type.
But which extension function will be invoked? one in the Base class or the one in Derived class ?
This depends on the type of object which invokes the call function, if you invoke the call with an Object of Base then the extension in the base class will be invoked and if you use the Derived object then the extension in Derived class will be invoked.

Spock and internal kotlin function

I am having trouble with using internal kotlin functions in my Spock tests. Here's short snippet of my spock test:
private def preconditions = new MonetaryPreconditions()
private def usdMonetary = new Monetary(BigDecimal.ZERO, Currency.USD)
def "should throw nothing because Monetaries currencies are same"(){
when:
preconditions.checkMonetariesCurrencies(usdMonetary , usdMonetary )
then:
noExceptionThrown()
}
and my MonetaryPreconditions class:
internal object MonetaryPreconditions {
internal fun checkMonetariesCurrencies(monetary1: Monetary, monetary2: Monetary) {
if (monetary1.currency != monetary2.currency) {
throw CurrencyMismatchException(arrayOf(monetary1.currency, monetary2.currency), "Compared currencies does not match: " + monetary1.currency
+ " , " + monetary2.currency)
}
}
}
My test fails with a stacktrace:
groovy.lang.MissingMethodException: No signature of method: touk.recruitment.parkandrest.parkingmanagement.core.monetary.MonetaryPreconditions.checkMonetariesCurrencies() is applicable for argument types: (touk.recruitment.parkandrest.parkingmanagement.core.monetary.Monetary, touk.recruitment.parkandrest.parkingmanagement.core.monetary.Monetary) values: [touk.recruitment.parkandrest.parkingmanagement.core.monetary.Monetary#7c417213, ...]
The problem lies in internal visibility of my checkMonetariesCurrencies function. If I change it to public it works just fine, however I do want this to be module private. How can I achieve that with Spock?
Other information about my project:
Test class and MonetaryPreconditions have same package.
I am using Maven.
Test class and MonetaryPreconditions are of course in the same module.
I just ran into the same issue, and the workaround I used (suggested by an experienced coworker of mine) was to write a wrapper class in Kotlin (in the same package as the class under test (CUT); I placed the source code file in the test/kotlin folder) and just forward function calls to the CUT. I then used the wrapper class in my groovy unit test code.
Further, calling functions defined within an object in Kotlin from another programming language requires you to access the object's INSTANCE variable, e.g.
MonetaryPreconditions.INSTANCE.myfunction
In your case, the wrapper may look as follows:
package com.yourpackage
object MonetaryPreconditionsWrapper{
fun checkMonetariesCurrencies(monetary1: Monetary, monetary2: Monetary){
MonetaryPreconditions.checkMonetariesCurrencies(monetary1, monetary2)
}
}
Now you can test the MonetaryPreconditions.checkMonetariesCurrencies function by simply calling the wrapper function from the groovy code as follows:
MonetaryPreconditionsWrapper.INSTANCE.checkMonetariesCurrencies(monetary1, monetary2)
Thanks you Giuseppe for your answer. However for me, Spock didn't see the wrapper as it thought it was a property of the test class and threw a groovy.lang.MissingPropertyException. I had add this to build.gradle:
compileTestGroovy.classpath += files(compileTestKotlin.destinationDir)
Taken from here: https://localcoder.org/test-classes-in-groovy-dont-see-test-classes-in-kotlin

Difference between function receiver and extension function

I was reading about Kotlin and did not quite get the idea
from What I understood extension function gives ability to a class with new functionality without having to inherit from the class
and what is receiver the same except it can be assigned to variable
Is there anything else about it?
Can someone give some examples on it
Extension functions:
Like Swift and C#, Kotlin provides the ability to extend a class with new functionality without having to modify the class or inherit from the class.
You might wonder why? Because we cannot edit and add functions to the language or SDK classes. So we end up creating Util classes in Java. I believe all the projects have a bunch of *Utils classes to put the helper methods that are used at multiple places in the code base. Extensions functions help to fix this Util problem.
How do we write a helper method in Java to find whether the given long value refers to today?
public class DateUtils {
public static boolean isToday(long when) {
// logic ...
}
}
And we call that method by passing the long value as an argument:
void someFunc(long when) {
boolean isToday = DateUtils.isToday(when);
}
In Kotlin, we can extend the Long class to include the isToday() function in it. And we can call the isToday() function on the Long value itself like any other member functions in the class.
// Extension function
fun Long.isToday(): Boolean {
// logic ...
}
fun someFunc(time: Long) {
val isToday = time.isToday()
}
Compared to the Util methods, Kotlin provides a much richer syntax using the Extension functions.
This improves the readability of the code which in turns improves its maintainability. And we get a little help from the code completion of the IDE. So we don't have to remember which Util class to use for the desired function.
Under the hood, Kotlin compiler generates the static helper methods as though we had written them as Java static Util methods. So we get this nice and richer syntax in Kotlin without sacrificing any performance.
Similar to functions, Kotlin also supports extension properties where we can add a property to an existing class.
Higher order functions:
A higher-order function is a function that takes functions as parameters, or returns a function.
Lets look at how a higher order function is written.
fun execute(x: Int, y: Int, op: (Int, Int) -> Int): Int {
return op(x, y)
}
Here the third parameter ( op ) is a function and so it makes this function a higher order function. The type of the parameter op is a function that takes 2 Ints as parameter and returns a Int.
To invoke this Higher order function, we can pass a function or a lambda expression:
execute(5, 5) { a, b -> a + b }
Receiver (or Function literal with Receiver or Lambda with Recevier):
A Higher order function that takes an extension function as its parameter is called Lambda with Receiver.
Let's look at the implementation of the apply function which is available in the Kotlin standard library.
inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
The function we pass to this apply function is actually an extension function to the type T. So in the lambda function, we can access the properties and the functions of the type T as though we are writing this function inside class T itself.
Here the generic type T is the receiver and we are passing a lambda function, hence the name Lambda with Receiver.
Another Example:
inline fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {
beginTransaction()
try {
func()
setTransactionSuccessful()
} finally {
endTransaction()
}
}
Here, the inTransaction() is an Extension function to the SQLiteDatabase class and the parameter of the inTransaction() function is also an extension function to the SQLiteDatabase class. Here SQLiteDatabase is the receiver, for the lambda that is passed as the argument.
To invoke that function:
db.inTransaction {
delete( ... )
}
Here the delete() is the function of the SQLiteDatabase class and since the lambda we pass is an Extension function to the receiver SQLiteDatabase we can access the delete function without any additional qualifiers with it, as though we are calling the function from inside the SQLiteDatabase class itself.
While #Bob's answer is far more informative on Kotlin than could I hope to be, including extension functions, it doesn't directly refer to the comparison between "function literals with receiver" as described in https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver and extension functions (https://kotlinlang.org/docs/reference/extensions.html). I.e. the difference between:
val isEven: Int.() -> Boolean = { this % 2 == 0 }
and
fun Int.isEven(): Boolean = this % 2 == 0
The receiver part of the name refers to both of these syntaxes receiving the base Int argument as this.
As I understand it, the difference between the two is simply between one being an expression confirming to a function type and the other a declaration. Functionally they are equivalent and can both be called as:
when { myNumber.isEven() -> doSomething(myNumber) }
but one is intended for use in extension libraries, while the other is typically intended for use as an argument for a function with a function-type parameter, particularly the Kotlin builder DSLs.