Mockito ArgumentCaptor for Kotlin function - mockito

Consider a function that takes an interface implementation as an argument like this:
interface Callback {
fun done()
}
class SomeClass {
fun doSomeThing(callback: Callback) {
// do something
callback.done()
}
}
When I want to test the caller of this function, I can do something like
val captor = ArgumentCaptor.forClass(Callback::class)
Mockito.verify(someClass).doSomeThing(captor.capture())
To test what the other class does when the callback is invoked, I can then do
captor.value.done()
Question: How can I do the same if I replace the callback interface with a high order function like
fun doSomeThing(done: () -> Unit) {
// do something
done.invoke()
}
Can this be done with ArgumentCaptor and what class do I have to use in ArgumentCaptor.forClass(???)

I recommend nhaarman/mockito-kotlin: Using Mockito with Kotlin
It solves this through an inline function with a reified type parameter:
inline fun <reified T : Any> argumentCaptor() = ArgumentCaptor.forClass(T::class.java)
Source: mockito-kotlin/ArgumentCaptor.kt at a6f860461233ba92c7730dd42b0faf9ba2ce9281 ยท nhaarman/mockito-kotlin
e.g.:
val captor = argumentCaptor<() -> Unit>()
verify(someClass).doSomeThing(captor.capture())
or
val captor: () -> Unit = argumentCaptor()
verify(someClass).doSomeThing(captor.capture())

I tried what #mfulton26 suggested, but was getting an error message saying captor.capture() must not be null. and this was what worked for me.
Declared a member variable captor with #Captor annotation,
#Captor private lateinit var captor: ArgumentCaptor<Callback>
and in my #Test,
verify(someClass).doSomething(capture(captor))

I had this problem just now and solved it with an inline argumentCaptor from mockito-kotlin:
argumentCaptor<String>().apply {
verify(myClass, times(2)).setItems(capture())
assertEquals(2, allValues.size)
assertEquals("test", firstValue)
}
firstValue is a reference to the first captured object.
Source: https://github.com/mockito/mockito-kotlin/wiki/Mocking-and-verifying#argument-captors

Based on mfulton26's answer, i create an example below.
to show how to invoke the captured function or lambda expression.
you need the mockito-kotlin
Assume we have a Class A, it has a suspend function with two higher order function as parameters.
how can we mock the onSuccess scenario and onError scenario
class A {
suspend fun methodB(onSuccess: (ModelA) -> Unit, onError: (ErrorA) -> Unit)
}
Here is the dummy example
// in the unit test class
private val mockClassA = // use annotation or mock()
// decalre the higer oder function capture variables.
private val onSuccessCapture = argumentCaptor<(ModelA) -> Unit>()
private val onErrorCapture = argumentCaptor<(ErrorA) -> Unit>()
#Test
fun testMethodB = testDispatcher.runBlockingTest {
doAnswer {
// on success scenario
val modelA = // get ModelA
onSuccessCapture.firstValue.invoke(modelA) // this line will let the onSuccess parameter been called
// on error scenario
// val errorA = // get ErrorA
//onErrorCapture.firstValue.invoke(errorA)
}.`when`(mockClassA).methodB(onSuccessCapture.capture(), onErrorCapture.capture())
}

Related

When extending an interface, should we use object keyword?

I have two different pieces of code. In one i need to use object and in the second i'm not.
Can someone explain me the difference between the situation:
first Code:
private val onInitWebResponseHandler: VolleyHandler.WebResponseHandler = VolleyHandler.WebResponseHandler()
{
Thread(ParseJsonStringOnInit(WeakReference(this),
weakRefIOnAllScoresDataFirstFetched, it)).start()
}
Second Code:
val competitionOrderLevelComparator : Comparator<CompetitionObj> = object : Comparator<CompetitionObj> {
override fun compare(object1: CompetitionObj, object2: CompetitionObj): Int
{
return object1.orderLevel - object2.orderLevel
}
}
fun interface WebResponseHandler
{
fun onWebResponseFinished(jsonString:String?)
}
In addition how the first code, we can have () brackets if interface doesn't have a constructor?

Kotlin anonymous object inheriting from base class but keeping derived class properties

I have a problem that I am not quire sure how to figure out elegantly:
abstract class BaseContinuousSingleObjectiveFitnessFunction {
// Invoke should compute some function, like f(x) = x^2 + 3x + 5
abstract fun invoke(x: List<Double>): Double
// This is supposed to take a function that will be called on the result of invoke
// and return an object derived from this one that has its invoke overriden to call
// the new function on the result of the original one.
fun modify(f: (Double) -> Double): BaseContinuousSingleObjectiveFitnessFunction {
val originalFunction = this
return object : BaseContinuousSingleObjectiveFitnessFunction() {
override operator fun invoke(x: List<Double>): Double = f(originalFunction(x))
}
}
}
Now, this works, but modify does not preserve the properties of the derived types.
So for example lets say I add this to the project:
class XTimesA(val a: Double): BaseContinuousSingleObjectiveFitnessFunction() {
override operator fun invoke(x: List<Double>) = x.sumByDouble { a*it }
}
Then I want to call modify on it:
val f1 = XTimesA(a = 5.0)
println(f1.a) // Works
val f2 = f1.modify { it.pow(2) }
println(f2.a) // This fails because it is not recognized as deriving XTimesA
Is there a way to not copy-paste modify into every deriving class but still keep access to the properties?
If you want to be able to access the property value on all inheritance levels, you have to lift the property up to the base class:
abstract class BaseContinuousSingleObjectiveFitnessFunction<Value>(val value: Value) {
abstract fun invoke(x: List<Value>): Value
fun modify(f: (Value) -> Value): BaseContinuousSingleObjectiveFitnessFunction<Value> {
val originalFunction = this
return object : BaseContinuousSingleObjectiveFitnessFunction<Value>() {
override operator fun invoke(x: List<Value>): Value = f(originalFunction(x))
}
}
}
Value is a generic type here for the case that Double is not applicable in all cases. If all values are of type Double than the class wouldn't need this type parameter.
You can use F-bounded polymorphism for this. Something like
abstract class BaseContinuousSingleObjectiveFitnessFunction<T : BaseContinuousSingleObjectiveFitnessFunction<T>> {
// Invoke should compute some function, like f(x) = x^2 + 3x + 5
abstract operator fun invoke(x: List<Double>): Double
abstract fun construct(f: (List<Double>) -> Double): T
// This is supposed to take a function that will be called on the result of invoke
// and return an object derived from this one that has its invoke overriden to call
// the new function on the result of the original one.
fun modify(f: (Double) -> Double): T = construct { list -> f(this(x)) }
}
open class XTimesA(val a: Double): BaseContinuousSingleObjectiveFitnessFunction<XTimesA>() {
override operator fun invoke(x: List<Double>) = x.sumByDouble { a*it }
override fun construct(f: (List<Double>) -> Double) = object : XTimesA(a) {
override operator fun invoke(x: List<Double>) = f(x)
}
}
However, in this particular case I don't think it actually makes sense and your example shows why: f1.modify { it.pow(2) } represents the function x -> x.sumByDouble { 5 * it }.pow(2) which isn't x -> x.sumByDouble { a * it } for any a!

Kotlin function parameter with receiver, called from Groovy

Kotlin and Groovy both provide a way to write a high-order function where the function parameter has an implicit receiver.
Kotlin Version
class KotlinReceiver {
fun hello() {
println("Hello from Kotlin")
}
}
class KotlinVersion {
fun withReceiver(fn: KotlinReceiver.() -> Unit) {
KotlinReceiver().fn()
}
}
// And then I can call...
val foo = KotlinVersion()
foo.withReceiver { hello() }
Groovy Version
class GroovyReceiver {
void hello() {
println("Hello from Groovy")
}
}
class GroovyVersion {
void withReceiver(Closure fn) {
fn.resolveStrategy = Closure.DELEGATE_FIRST
fn.delegate = new GroovyReceiver()
fn.run()
}
}
// And then I can call...
def foo = new GroovyVersion()
foo.withReceiver { hello() }
My goal is to write the withReceiver function in Kotlin, but call it from groovy and have { hello() } work. As written, though, Kotlin generates bytecode like
public final void withReceiver(#NotNull Function1 fn) { /* ... */ }
which Groovy treats as a function with a parameter. In other words, to call Kotlin's withReceiver from Groovy, I have to do this:
(new KotlinVersion()).withReceiver { it -> it.hello() }
In order to allow { hello() } with no it -> it., I have to add an overload that takes a groovy.lang.Closure as its parameter.
Kotlin Version
import groovy.lang.Closure
class KotlinVersion {
fun withReceiver(fn: KotlinReceiver.() -> Unit) {
KotlinReceiver().fn()
}
fun withReceiver(fn: Closure<Any>) = withReceiver {
fn.delegate = this
fn.resolveStrategy = Closure.DELEGATE_FIRST
fn.run()
}
}
With that overload in place, given a KotlinVersion instance called foo the following line works in both languages:
// If this line appears in Groovy code, it calls the Closure overload.
// If it's in Kotlin, it calls the KotlinReceiver.() -> Unit overload.
foo.withReceiver { hello() }
I'm trying to keep that syntax, but avoid having to write that extra boilerplate overload for each high-order function my Kotlin library defines. Is there a better (more seamless/automatic) way of making Kotlin's function-with-receiver syntax usable from Groovy so I don't have to manually add a boilerplate overload to each of my Kotlin functions?
The complete code and compile instructions for my toy example above are on gitlab.
in groovy you can define new functions dynamically
KotlinVersion.metaClass.withReceiver = { Closure c->
delegate.with(c)
}
this will define new function withReceiver for class KotlinVersion
and will allow to use this syntax to KotlinVersion instance:
kv.withReceiver{ toString() }
in this case toString() will be called on kv
you can write the function that iterates through declared methods of your kotlin class with kotlin.Function parameter and declare new method but with groovy.lang.Closure parameter through metaClass.

Built-in 'with' type method that returns the object it was called on

In Kotlin, there is the apply method:
inline fun <T> T.apply(block: T.() -> Unit): T (source)
Calls the specified function block with this value as its receiver and returns this value.
This allows you to configure an object like the following:
val myObject = MyObject().apply {
someProperty = "this value"
myMethod()
}
myObject would be the MyObject after the apply {} call.
Groovy has the with method, which is similar:
public static <T,U> T with(U self,
#DelegatesTo(value=DelegatesTo.Target.class,target="self",strategy=1)
Closure<T> closure
)
Allows the closure to be called for the object reference self.
...
And an example from the doc:
def b = new StringBuilder().with {
append('foo')
append('bar')
return it
}
assert b.toString() == 'foobar'
The part with the Groovy method is always having to use return it to return the delegate of the with call, which makes the code considerably more verbose.
Is there an equivalent to the Kotlin apply in Groovy?
The function is called tap and is part of Groovy 2.5. See discussions about the naming in merge request.
Other than that, only foo.with{ bar=baz; it } can be used. You can retrofit your own doto, tap, apply, ... via metaprogramming.

How to pass context Implicitly for constructors in Kotlin

I am trying to make the construction of instances of a class depending on the scope in which they are defined without using explicit parameters.
This is part of a port from Python to Kotlin but the main idea would be something like:
var d = MyClass()
use_scope(contextAForScope) {
var a = MyClass()
use_scope(contextBForScope) {
var b=MyClass()
}
}
In this example the d constructor would use a default context, a constructor would use contextAForScope and b constructor would use contextBForScope (use_scope is just a placeholder here).
Something like implicit contexts?
Of course, I could make the constructor parameter explicit but this will potentially be used many times in a single scope and I would prefer not to define an additional variable.
class MyClass(val context: Int)
fun MyClass() = MyClass(0)
interface MyClassScope {
fun MyClass(): MyClass
}
object ContextAForScope : MyClassScope {
override fun MyClass() = MyClass(1)
}
object ContextBForScope : MyClassScope {
override fun MyClass() = MyClass(2)
}
inline fun useScope(scope: MyClassScope, block: MyClassScope.() -> Unit) {
scope.block()
}
fun main(args: Array<String>) {
val d = MyClass()
useScope(ContextAForScope) {
val a = MyClass()
useScope(ContextBForScope) {
val b = MyClass()
}
}
}
Use a factory function to create your class. If you name the function like the class, it looks like a constructor.
Define an interface with the same factory function and two objects for the scopes.
Define a function that takes the scope and the initializer block.
Now you can use the useScope-Function and within the block the right factory function is invoked.
with is what you are looking for:
class MyClass()
var d = MyClass()
fun main(args: Array<String>){
var c = "c: Could be any class"
var d = "d: Could be any class"
with(c) {
// c is "this"
var a = MyClass()
print(c) // prints "c: Could be any class"
with(d) {
// d is "this"
var b = MyClass()
}
// b is undefined in this scope
}
// a is undefined in this scope
}
with takes a lambda as argument an everything in that lambda is only defined in that scope.

Resources