Skip to content

Commit 27c6bf6

Browse files
authored
Merge pull request #111 from nhaarman/release-0.11.0
Release 0.11.0
2 parents 50a1b91 + 771f761 commit 27c6bf6

File tree

6 files changed

+111
-14
lines changed

6 files changed

+111
-14
lines changed

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,31 @@ inline fun <reified T : Any> createInstance() = createInstance(T::class)
6464

6565
@Suppress("UNCHECKED_CAST")
6666
fun <T : Any> createInstance(kClass: KClass<T>): T {
67+
var cause: Throwable? = null
6768
return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?:
68-
when {
69-
kClass.hasObjectInstance() -> kClass.objectInstance!!
70-
kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue()
71-
kClass.isMockable() -> kClass.java.uncheckedMock()
72-
kClass.isEnum() -> kClass.java.enumConstants.first()
73-
kClass.isArray() -> kClass.toArrayInstance()
74-
kClass.isClassObject() -> kClass.toClassObject()
75-
else -> kClass.easiestConstructor().newInstance()
69+
try {
70+
when {
71+
kClass.hasObjectInstance() -> kClass.objectInstance!!
72+
kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue()
73+
kClass.isEnum() -> kClass.java.enumConstants.first()
74+
kClass.isArray() -> kClass.toArrayInstance()
75+
kClass.isClassObject() -> kClass.toClassObject()
76+
kClass.isMockable() -> try {
77+
kClass.java.uncheckedMock()
78+
} catch(e: Throwable) {
79+
cause = e
80+
kClass.easiestConstructor().newInstance()
81+
}
82+
else -> kClass.easiestConstructor().newInstance()
83+
}
84+
} catch(e: Exception) {
85+
if (e is MockitoKotlinException) throw e
86+
87+
cause?.let {
88+
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
89+
(e as java.lang.Throwable).initCause(it)
90+
}
91+
throw MockitoKotlinException("Could not create an instance for $kClass.", e)
7692
}
7793
}
7894

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ inline fun <reified T : Any> mock(stubbing: KStubbing<T>.(T) -> Unit): T {
9494
class KStubbing<out T>(private val mock: T) {
9595
fun <R> on(methodCall: R) = Mockito.`when`(methodCall)
9696

97-
fun <R : Any> on(methodCall: T.() -> R, c: KClass<R>): OngoingStubbing<R> {
97+
fun <R : Any> onGeneric(methodCall: T.() -> R, c: KClass<R>): OngoingStubbing<R> {
9898
val r = try {
9999
mock.methodCall()
100100
} catch(e: NullPointerException) {
@@ -108,8 +108,16 @@ class KStubbing<out T>(private val mock: T) {
108108
return Mockito.`when`(r)
109109
}
110110

111-
inline fun <reified R : Any> on(noinline methodCall: T.() -> R): OngoingStubbing<R> {
112-
return on(methodCall, R::class)
111+
inline fun <reified R : Any> onGeneric(noinline methodCall: T.() -> R): OngoingStubbing<R> {
112+
return onGeneric(methodCall, R::class)
113+
}
114+
115+
fun <R> on(methodCall: T.() -> R): OngoingStubbing<R> {
116+
return try {
117+
Mockito.`when`(mock.methodCall())
118+
} catch(e: NullPointerException) {
119+
throw MockitoKotlinException("NullPointerException thrown when stubbing. If you are trying to stub a generic method, try `onGeneric` instead.", e)
120+
}
113121
}
114122
}
115123

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ interface Methods {
5454
fun nullableString(s: String?)
5555

5656
fun stringResult(): String
57+
fun nullableStringResult(): String?
5758
fun builderMethod(): Methods
5859
}
5960

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,24 @@ class CreateInstanceTest {
476476
expect(result.second).toBe(2)
477477
}
478478

479+
@Test
480+
fun sealedClass() {
481+
/* When */
482+
val result = createInstance(MySealedClass::class)
483+
484+
/* Then */
485+
expect(result).toNotBeNull()
486+
}
487+
488+
@Test
489+
fun sealedClassMember() {
490+
/* When */
491+
val result = createInstance(MySealedClass.MySealedClassMember::class)
492+
493+
/* Then */
494+
expect(result).toNotBeNull()
495+
}
496+
479497
private class PrivateClass private constructor(val data: String)
480498

481499
class ClosedClass
@@ -537,4 +555,8 @@ class CreateInstanceTest {
537555
}
538556

539557
enum class MyEnum { VALUE, ANOTHER_VALUE }
558+
559+
sealed class MySealedClass {
560+
class MySealedClassMember : MySealedClass()
561+
}
540562
}

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,20 @@ class MockitoTest {
351351
expect(result).toBeTheSameAs(mock)
352352
}
353353

354+
@Test
355+
fun testMockStubbing_nullable() {
356+
/* Given */
357+
val mock = mock<Methods> {
358+
on { nullableStringResult() } doReturn "Test"
359+
}
360+
361+
/* When */
362+
val result = mock.nullableStringResult()
363+
364+
/* Then */
365+
expect(result).toBe("Test")
366+
}
367+
354368
@Test
355369
fun testMockStubbing_doThrow() {
356370
/* Given */
@@ -438,10 +452,22 @@ class MockitoTest {
438452
}
439453

440454
@Test
441-
fun doReturn_withGenericIntReturnType() {
455+
fun doReturn_withGenericIntReturnType_on() {
456+
/* Expect */
457+
expectErrorWithMessage("onGeneric") on {
458+
459+
/* When */
460+
mock<GenericMethods<Int>> {
461+
on { genericMethod() } doReturn 2
462+
}
463+
}
464+
}
465+
466+
@Test
467+
fun doReturn_withGenericIntReturnType_onGeneric() {
442468
/* Given */
443469
val mock = mock<GenericMethods<Int>> {
444-
on { genericMethod() } doReturn 2
470+
onGeneric { genericMethod() } doReturn 2
445471
}
446472

447473
/* Then */

mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
import com.nhaarman.expect.expect
26+
import com.nhaarman.expect.expectErrorWithMessage
2627
import com.nhaarman.mockito_kotlin.*
2728
import org.junit.Test
2829
import java.io.IOException
@@ -105,7 +106,7 @@ class CreateInstanceInlineTest {
105106
/* Then */
106107
expect(i).toBe(0)
107108
}
108-
109+
109110
@Test
110111
fun createStringInstance() {
111112
/* When */
@@ -115,10 +116,33 @@ class CreateInstanceInlineTest {
115116
expect(s).toBe("")
116117
}
117118

119+
@Test
120+
fun sealedClass_fails() {
121+
/* Expect */
122+
expectErrorWithMessage("Could not create") on {
123+
124+
/* When */
125+
createInstance(MySealedClass::class)
126+
}
127+
}
128+
129+
@Test
130+
fun sealedClassMember() {
131+
/* When */
132+
val result = createInstance(MySealedClass.MySealedClassMember::class)
133+
134+
/* Then */
135+
expect(result).toNotBeNull()
136+
}
137+
118138
interface Methods {
119139

120140
fun throwableClass(t: ThrowableClass)
121141
}
122142

123143
class ThrowableClass(cause: Throwable) : Throwable(cause)
144+
145+
sealed class MySealedClass {
146+
class MySealedClassMember : MySealedClass()
147+
}
124148
}

0 commit comments

Comments
 (0)