Skip to content

Commit 55e9a3c

Browse files
committed
Merge pull request #30 from nhaarman/release-0.3.1
Release 0.3.1
2 parents 48fc1aa + df0c3f6 commit 55e9a3c

File tree

5 files changed

+81
-14
lines changed

5 files changed

+81
-14
lines changed

.travis.yml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,3 @@ install:
1414

1515
script:
1616
- ./gradlew test
17-
18-
before_cache:
19-
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
20-
- rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties.lock
21-
- rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties
22-
cache:
23-
directories:
24-
- $HOME/.gradle/caches
25-
- $HOME/.gradle/daemon
26-
- $HOME/.gradle/native
27-
- $HOME/.gradle/wrapper

mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ package com.nhaarman.mockito_kotlin
2727

2828
import org.mockito.Answers
2929
import org.mockito.internal.creation.MockSettingsImpl
30+
import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor
3031
import org.mockito.internal.util.MockUtil
3132
import java.lang.reflect.Modifier
3233
import java.lang.reflect.ParameterizedType
@@ -37,6 +38,7 @@ import kotlin.reflect.KType
3738
import kotlin.reflect.defaultType
3839
import kotlin.reflect.jvm.isAccessible
3940
import kotlin.reflect.jvm.javaType
41+
import kotlin.reflect.jvm.jvmName
4042

4143
/**
4244
* A collection of functions that tries to create an instance of
@@ -54,16 +56,38 @@ fun <T : Any> createInstance(kClass: KClass<T>): T {
5456
kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue()
5557
kClass.isEnum() -> kClass.java.enumConstants.first()
5658
kClass.isArray() -> kClass.toArrayInstance()
57-
else -> kClass.constructors.sortedBy { it.parameters.size }.first().newInstance()
59+
kClass.isClassObject() -> kClass.toClassObject()
60+
else -> kClass.easiestConstructor().newInstance()
5861
}
5962
}
6063

64+
/**
65+
* Tries to find the easiest constructor which it can instantiate.
66+
*/
67+
private fun <T : Any> KClass<T>.easiestConstructor(): KFunction<T> {
68+
return constructors.firstOrDefault(
69+
{
70+
it.parameters.filter {
71+
it.type.toString().toLowerCase().contains("array")
72+
}.isEmpty()
73+
},
74+
{
75+
constructors.sortedBy { it.parameters.size }.first()
76+
}
77+
)
78+
}
79+
80+
private fun <T> Collection<T>.firstOrDefault(predicate: (T) -> Boolean, default: () -> T): T {
81+
return firstOrNull(predicate) ?: default()
82+
}
83+
6184
@Suppress("SENSELESS_COMPARISON")
6285
private fun KClass<*>.hasObjectInstance() = objectInstance != null
6386

6487
private fun KClass<*>.isMockable() = !Modifier.isFinal(java.modifiers)
6588
private fun KClass<*>.isEnum() = java.isEnum
6689
private fun KClass<*>.isArray() = java.isArray
90+
private fun KClass<*>.isClassObject() = jvmName.equals("java.lang.Class")
6791
private fun KClass<*>.isPrimitive() =
6892
java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf(
6993
"Boolean",
@@ -104,6 +128,11 @@ private fun <T : Any> KClass<T>.toArrayInstance(): T {
104128
} as T
105129
}
106130

131+
@Suppress("UNCHECKED_CAST")
132+
private fun <T : Any> KClass<T>.toClassObject(): T {
133+
return Class.forName("java.lang.Object") as T
134+
}
135+
107136
private fun <T : Any> KFunction<T>.newInstance(): T {
108137
isAccessible = true
109138
return callBy(parameters.associate {
@@ -132,5 +161,7 @@ private fun <T : Any> KType.createNullableInstance(): T? {
132161
private fun <T> Class<T>.uncheckedMock(): T {
133162
val impl = MockSettingsImpl<T>().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl<T>
134163
val creationSettings = impl.confirm(this)
135-
return MockUtil().createMock(creationSettings)
164+
return MockUtil().createMock(creationSettings).apply {
165+
(this as MockMethodInterceptor.MockAccess).mockitoInterceptor = null
166+
}
136167
}

mockito-kotlin/src/test/kotlin/Classes.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ interface Methods {
4949
fun closedSet(s: Set<Closed>)
5050
fun string(s: String)
5151
fun closedVararg(vararg c: Closed)
52+
fun throwableClass(t: ThrowableClass)
5253

5354
fun stringResult(): String
54-
}
55+
}
56+
57+
class ThrowableClass(cause: Throwable) : Throwable(cause)

mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import com.nhaarman.expect.expect
2727
import com.nhaarman.mockito_kotlin.createInstance
2828
import org.junit.Test
29+
import java.util.*
30+
import kotlin.reflect.KClass
2931

3032
class CreateInstanceTest {
3133

@@ -368,6 +370,39 @@ class CreateInstanceTest {
368370
expect(result).toNotBeNull()
369371
}
370372

373+
@Test
374+
fun classObject() {
375+
/* When */
376+
val result = createInstance<Class<String>>()
377+
378+
/* Then */
379+
expect(result).toNotBeNull()
380+
}
381+
382+
@Test
383+
fun kClassObject() {
384+
/* When */
385+
val result = createInstance<KClass<String>>()
386+
387+
/* Then */
388+
expect(result).toNotBeNull()
389+
}
390+
391+
@Test
392+
fun uuid() {
393+
/**
394+
* The UUID class has a single-argument constructor that expects an array with some specific contents.
395+
* We avoid these types of constructors by calling another constructor, if available.
396+
* In this case, UUID(Long, Long).
397+
*/
398+
399+
/* When */
400+
val result = createInstance<UUID>()
401+
402+
/* Then */
403+
expect(result).toBeEqualTo(UUID(0, 0))
404+
}
405+
371406
private class PrivateClass private constructor(val data: String)
372407

373408
class ClosedClass

mockito-kotlin/src/test/kotlin/MockitoTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import com.nhaarman.expect.expectErrorWithMessage
33
import com.nhaarman.mockito_kotlin.*
44
import org.junit.Test
55
import org.mockito.exceptions.base.MockitoAssertionError
6+
import java.io.IOException
67

78
/*
89
* The MIT License
@@ -107,6 +108,14 @@ class MockitoTest {
107108
}
108109
}
109110

111+
@Test
112+
fun anyThrowableWithSingleThrowableConstructor() {
113+
mock<Methods>().apply {
114+
throwableClass(ThrowableClass(IOException()))
115+
verify(this).throwableClass(any())
116+
}
117+
}
118+
110119
@Test
111120
fun listArgThat() {
112121
mock<Methods>().apply {

0 commit comments

Comments
 (0)