Kotlin Mockito Generics - kotlin

Suppose my class is:
open class TestThis{
#Autowired
private var myService : MyService? = null
fun doMyFunction(){
val result = myService.doSomething("hello world", Function { entry ->
var retVal : Boolean = false
//some processing
retVal
})
}
}
#Service
open class MyService{
fun doSomething(str1 : String, java.util.Function<MyCrap, Boolean>) : List<String>{
//do something here
}
}
#RunWith(MockitoJUnitRunner::class)
class TestThisTest{
#Mock
var myService : MyService? = null
#InjectMocks
var test : TestThis? = null
#Before
fun before(){
val list : List<String> = //init list
//this line causes compilation error due to generics. error 1
Mockito.`when`(myService.doSomething(Mockito.anyString(), Mockito.any(Function::class.java))).thenReturn(list)
//this line also causes compilation error due to generics. error 2
Mockito.`when`(myService.doSomething(Mockito.anyString(), Mockito.any(Function<MyCrap, Boolean>::class.java))).thenReturn(list)
}
}
error 1:
Type inference failed. Expected type mismatch.
error 2:
Only classes are allowed on the left hand side of a class literal
So, how do I mock myService#doSomething?

Getting matchers to work with Kotlin can be a problem.
If you have a method written in Kotlin that does not take a nullable parameter then we cannot match with it using Mockito.any(). This is because it returns null and this is not assignable to a non-nullable parameter.
in Kotlin classes and members are final by default, we need to open them, because mocking is prohibit for final methods
Generic classes mocks rise errors like you described Only classes are allowed on the left hand side of a class literal
All these problems can be resolved via simple MockitoUtils class:
object MockitoUtils {
inline fun <reified T> anyObject(): T {
return Mockito.any(T::class.java) ?: createInstance()
}
inline fun <reified T : Any> createInstance(): T {
return when (T::class) {
Boolean::class -> false as T
Byte::class -> 0.toByte() as T
Char::class -> 0.toChar() as T
Short::class -> 0.toShort() as T
Int::class -> 0 as T
Long::class -> 0L as T
Float::class -> 0f as T
Double::class -> 0.0 as T
else -> createInstance(T::class)
}
}
fun <T : Any> createInstance(kClass: KClass<T>): T {
return castNull()
}
#Suppress("UNCHECKED_CAST")
private fun <T> castNull(): T = null as T
}
Example of usage:
Mockito.`when`(myService!!.doSomething(Mockito.anyString(), MockitoUtils.anyObject())).thenReturn(list)
Service to mock:
open class MyService {
open fun doSomething(str1 : String, func : java.util.function.Function<MyCrap, Boolean>) : List<String>{
return emptyList()
}
}
Service to test:
open class TestThis{
private var myService : MyService? = null
fun doMyFunction() : List<String>? {
val result = myService?.doSomething("hello world", java.util.function.Function { entry ->
var retVal : Boolean = false
//some processing
retVal
} )
return result;
}
}
Test impplementation:
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnitRunner
import kotlin.reflect.KClass
#RunWith(MockitoJUnitRunner::class)
class TestThisTest{
#Mock
var myService : MyService? = null
#InjectMocks
var test : TestThis? = null
#Before
fun before(){
val list : ArrayList<String> = arrayListOf()
list.add("123")
val thenReturn = Mockito.`when`(myService!!.doSomething(Mockito.anyString(), MockitoUtils.anyObject())).thenReturn(list)
}
#Test
fun test() {
val list = test!!.doMyFunction()
Assert.assertTrue(list!!.contains("123"))
}
object MockitoUtils {
inline fun <reified T> anyObject(): T {
return Mockito.any(T::class.java) ?: createInstance()
}
inline fun <reified T : Any> createInstance(): T {
return when (T::class) {
Boolean::class -> false as T
Byte::class -> 0.toByte() as T
Char::class -> 0.toChar() as T
Short::class -> 0.toShort() as T
Int::class -> 0 as T
Long::class -> 0L as T
Float::class -> 0f as T
Double::class -> 0.0 as T
else -> createInstance(T::class)
}
}
fun <T : Any> createInstance(kClass: KClass<T>): T {
return castNull()
}
#Suppress("UNCHECKED_CAST")
private fun <T> castNull(): T = null as T
}
}
Alternative solution:
Another possible solution would be to use a library like mockito-kotlin.
Maven:
<dependency>
<groupId>org.mockito.kotlin</groupId>
<artifactId>mockito-kotlin</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>

You should not mock "TestThis" when you try to test something inside this Service. If you mock it there is nothing "inside". It is just a mock.
Try instanciating it and then inject a mock of MyService.
It also seems weird where you are writing your Test. Why is a Unit test for MyService in the testclass TestThisTest. You should creat your own Unit test for MyService.

Related

in test with ktlin, how to verify the internal constructor

Having a kotlin class
internal class NotificationManager internal constructor(context: Context) : Base(context) {...}
The test was in java and have been working:
#Test
public void verify_internal_Constructor() {
KClass<?> kClass = JvmClassMappingKt.getKotlinClass(NotificationManager.class);
boolean hasPublicConstructor = kClass.getConstructors().stream()
.map(KFunction::getVisibility)
.filter(Objects::nonNull) // package-private and java-protected are null
.anyMatch(kVisibility -> kVisibility.equals(KVisibility.PUBLIC));
assertFalse(hasPublicConstructor);
}
But after convert the test into kotlin, it gets compile error:
fun verify_internal_Constructor() {
val kClass: KClass<*> = NotificationManager::class.java.kotlin
val hasPublicConstructor = kClass.constructors.stream()
.map<KVisibility>(::kotlin.reflect.KCallable.visibility) //<===
.filter { obj: KVisibility? ->
Objects.nonNull(
obj
)
} // package-private and java-protected are null
.anyMatch { kVisibility: KVisibility -> kVisibility == KVisibility.PUBLIC }
assertFalse(hasPublicConstructor)
}
how to map the visibility?

Is it possible to verify at compile time whether the required function is called for the Factory Class in Kotlin?

class ModelFactory {
fun setA() : ModelFactory {
// blabla...
}
fun setB() : ModelFactory {
// blabla...
}
fun setC() : ModelFactory {
// blabla...
}
fun build() : Model {
// An error occurs if any of setA, setB, and setC is not called.
}
}
//example
fun successTest() {
ModelFactory().setA().setB().setC().build() // No error occurs at compile time
}
fun failTest() {
ModelFactory().setA().build() // An error occurs at compile time because setB and setC are not called.
}
It's awkward grammatically, but I think it's been expressed what I want.
I have already implemented an error-raising runtime for this requirement, but I want to check this at compile time.
If possible, I think I should use annotations. But is this really possible at compile time?
With Kotlin, I have been avoiding builder pattern, as we can always specify default values for non-mandatory fields.
If you still want to use a builder pattern, you can use Step builder pattern that expects all mandatory fields to be set before creating the object. Note that each setter method returns the reference of next setter interface. You can have multiple Step builders based on the combination of mandatory fields.
class Model(val a: String = "", val b: String = "", val c: String = "")
class StepBuilder {
companion object {
fun builder(): AStep = Steps()
}
interface AStep {
fun setA(a: String): BStep
}
interface BStep {
fun setB(b: String): CStep
}
interface CStep {
fun setC(c: String): BuildStep
}
interface BuildStep {
//fun setOptionalField(x: String): BuildStep
fun build(): Model
}
class Steps : AStep, BStep, CStep, BuildStep {
private lateinit var a: String
private lateinit var b: String
private lateinit var c: String
override fun setA(a: String): BStep {
this.a = a
return this
}
override fun setB(b: String): CStep {
this.b = b
return this
}
override fun setC(c: String): BuildStep {
this.c = c
return this
}
override fun build() = Model(a, b , c)
}
}
fun main() {
// cannot build until you call all three setters
val model = StepBuilder.builder().setA("A").setB("B").setC("C").build()
}

How to create an instance of a class by passing the type

I want to be able to say make an instance of this class and give a type then the code can instantiate a new instance of that class.
fun maker(type: Class<Animal>): Animal {
if(type == Class<Dog>) {
return Dog()
}
else if (type == Class<Cat>) {}
...
}
What is a good way to do this?
If they all have zero-argument constructors, you can do:
fun maker(type: Class<Animal>): Animal {
return type.newInstance()
}
You can make it return the type that was passed in for a little more versatility:
fun <T: Animal> maker(type: Class<T>): T {
return type.newInstance()
}
Correct version following your example (not sure if best approach overall):
fun <T: Animal> maker(type: Class<T>): T? {
return when (type) {
Cat::class.java -> Cat() as T
Dog::class.java -> Dog() as T
else -> null
}
}
And then to create objects:
val a = maker(Cat::class.java)
val b = maker(Dog::class.java)
(Updated) I am not an expert in Kotlin but you can do something like this :
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
class A {
fun greet() {
println("Hello A");
}
}
class B{
fun greet() {
println("Hello B");
}
}
fun <T : Any> maker(clazz: KClass<T>): T {
return clazz.createInstance();
}
val aObj = maker<A>(A::class);
aObj.greet();
val bObj = maker<B>(B::class);
bObj.greet();
Output:
Hello A
Hello B
I hope now it makes sense you just need to pass the class to the method and it returns an object.
As you will be using Animal as a parent class so you can replace Any => Animal
fun <T : Animal> maker(clazz: KClass<T>): T {
return clazz.createInstance();
}
If the function can be inline you can also use reified type
inline fun<reified T: Animal> make() = T::class.createInstance()
...
val dog = make<Dog>()
Please notice that to use createInstance() the class must have no-arg constructor or IllegalArgumentException will be thrown

Scope Resolution Operator in Kotlin

I have read the following syntax. I have no idea why scope resolution operator is used in it.
class XyzFragment : Fragment() {
lateinit var adapter: ChatAdapter
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
if (!::adapter.isInitialized) { <-- This one
adapter = ChatAdapter(this, arrayListOf())
}
}
}
I want to know what is :: in if (!::adapter.isInitialized) { statement.
:: is a short form for this:: in Kotlin.
:: is a operator to creates a member reference or a class reference. For example,
class Test {
fun foo() {
}
fun foo2(value: Int) {
}
fun bar() {
val fooFunction = ::foo
fooFunction.invoke() // equals to this.foo()
val foo2Function = ::foo2
foo2Function.invoke(1) // equals to this.foo2(1)
val fooFunction2 = Test::foo
val testObject = Test()
fooFunction2.invoke(this) // equals to this.foo()
fooFunction2.invoke(testObject) // equals to testObject.foo()
}
}
This is mainly used in reflection and passing function.

Observable property allowing to add observers at runtime

Via Delegates.observable, Kotlin permits observable properties. I need, however, the ability of adding observers at runtime, as Java's Observable class does.
What I have now, is the following:
import java.util.*
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0
import kotlin.reflect.jvm.isAccessible
class MyObservable<T> (var v: T): java.util.Observable() {
operator fun getValue(thisRef: Any, prop: KProperty<*>) = v
operator fun setValue(thisRef: Any, prop: KProperty<*>, newValue: T) {
v = newValue
setChanged()
notifyObservers()
}
}
fun <T> addObserver(prop: KProperty0<T>, observerFn: (T) -> Unit) =
(prop.apply{ isAccessible = true }.getDelegate() as MyObservable<T>)
.addObserver(Observer({ o, _ -> observerFn((o as MyObservable<T>).v) }))
class ObservableExample {
var i: Int by MyObservable(3)
}
fun main(args: Array<String>) {
val ex: ObservableExample = ObservableExample();
addObserver(ex::i, { println(it) })
ex.i = 7
ex.i = 9
// prints:
// 7
// 9
}
It works, but it feels like reinventing the wheel.
Isn't there a standard solution for this?
If not, is what I've done correct?
A slightly shorter variant of the same idea:
import kotlin.properties.Delegates
typealias IntObserver = (Int) -> Unit
class ObservableExample {
val prop1Observers = mutableListOf<IntObserver>()
var prop1: Int by Delegates.observable(0) { prop, old, new ->
prop1Observers.forEach { it(new) }
}
}
fun main(args: Array<String>) {
val example = ObservableExample()
example.prop1Observers.add({ println(it) })
example.prop1 = 1
example.prop1 = 2
}
The output is as expected. Probably, it is better to make observers property private and add a method to add subscribers but I omitted it for the simplicity.
This is because you starts with a simple example, and can't find the benefits of Kotlin delegated properties.
Kotlin doesn't forcing you to implements any interface to supports delegated properties, yon can using delegated properties in Kotlin just provide getValue & setValue(?) operators. and their visibility even can be private.
Kotlin provided a provideDelegate operator function since 1.1, that let you manage/control how to create a delegate.
The delegate in Kotlin is working in the background, which means it is invisible from the source code point of view, and let the code source treat a delegated properties as a regular properties.
Kotlin delegated properties can easily let you manage java beans without using PropertyEditorSupport in Java, and you don't need to manage the delegate at all in Kotlin, just to notify the changed property only. for example:
val history = mutableMapOf<String, MutableList<Pair<Any?, Any?>>>()
val subject = Subject()
subject.subscribe { event ->
val each = history.getOrPut(event.propertyName) { mutableListOf() }
each.add(event.oldValue to event.newValue)
}
// v--- treat a delegated property as regular property
subject.number = 1
subject.string = "bar"
subject.number = 2
println(history);
// ^--- {"number":[<null,1>,<1,2>], "string": [<null,"bar">]}
Note: the getValue & setValue operator functions private below.
class Subject {
// v--- manage the delegated property internally
var string: String? by this
var number: Int? by this
private val properties by lazy {
mutableMapOf<Any?, Any?>()
}
private val listeners by lazy {
mutableListOf<PropertyChangeListener>()
}
private operator #Suppress("UNCHECKED_CAST")
fun <T : Any?> getValue(self: Any, prop: KProperty<*>): T {
return properties[prop.name] as T
}
private operator
fun <T : Any?> setValue(self: Any,prop: KProperty<*>, newValue: T) {
val event = PropertyChangeEvent(
self,
prop.name,
properties[prop.name],
newValue
)
properties[prop.name] = newValue
listeners.forEach { it.propertyChange(event) }
}
fun subscribe(listener: (event: PropertyChangeEvent) -> Unit) {
subscribe(PropertyChangeListener { listener(it) })
}
fun subscribe(subscriber: PropertyChangeListener) {
listeners.add(subscriber)
}
}