Skip to content

Commit 494e7ca

Browse files
authored
Merge pull request #105 from nhaarman/fix-generic-returntype-npe
Catch an NPE thrown by the Kotlin type checker in the Mockito library.
2 parents 3b5c40a + 113d9e9 commit 494e7ca

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,24 @@ inline fun <reified T : Any> mock(stubbing: KStubbing<T>.(T) -> Unit): T {
9393

9494
class KStubbing<out T>(private val mock: T) {
9595
fun <R> on(methodCall: R) = Mockito.`when`(methodCall)
96-
fun <R> on(methodCall: T.() -> R) = Mockito.`when`(mock.methodCall())
96+
97+
fun <R : Any> on(methodCall: T.() -> R, c: KClass<R>): OngoingStubbing<R> {
98+
val r = try {
99+
mock.methodCall()
100+
} catch(e: NullPointerException) {
101+
// An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a
102+
// null value for a non-nullable generic type.
103+
// We catch this NPE to return a valid instance.
104+
// The Mockito state has already been modified at this point to reflect
105+
// the wanted changes.
106+
createInstance(c)
107+
}
108+
return Mockito.`when`(r)
109+
}
110+
111+
inline fun <reified R : Any> on(noinline methodCall: T.() -> R): OngoingStubbing<R> {
112+
return on(methodCall, R::class)
113+
}
97114
}
98115

99116
infix fun <T> OngoingStubbing<T>.doReturn(t: T): OngoingStubbing<T> = thenReturn(t)

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ interface Methods {
5454
fun nullableString(s: String?)
5555

5656
fun stringResult(): String
57-
fun builderMethod() : Methods
57+
fun builderMethod(): Methods
58+
}
59+
60+
interface GenericMethods<T> {
61+
fun genericMethod(): T
5862
}
5963

6064
class ThrowableClass(cause: Throwable) : Throwable(cause)

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,4 +436,15 @@ class MockitoTest {
436436
expect(mock.stringResult()).toBe("a")
437437
expect(mock.stringResult()).toBe("b")
438438
}
439+
440+
@Test
441+
fun doReturn_withGenericIntReturnType() {
442+
/* Given */
443+
val mock = mock<GenericMethods<Int>> {
444+
on { genericMethod() } doReturn 2
445+
}
446+
447+
/* Then */
448+
expect(mock.genericMethod()).toBe(2)
449+
}
439450
}

0 commit comments

Comments
 (0)