diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index cab7694e..72ceb6af 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -67,8 +67,8 @@ fun createInstance(kClass: KClass): T { return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?: when { kClass.hasObjectInstance() -> kClass.objectInstance!! - kClass.isMockable() -> kClass.java.uncheckedMock() kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() + kClass.isMockable() -> kClass.java.uncheckedMock() kClass.isEnum() -> kClass.java.enumConstants.first() kClass.isArray() -> kClass.toArrayInstance() kClass.isClassObject() -> kClass.toClassObject() diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 86fc85da..0b326997 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -93,7 +93,24 @@ inline fun mock(stubbing: KStubbing.(T) -> Unit): T { class KStubbing(private val mock: T) { fun on(methodCall: R) = Mockito.`when`(methodCall) - fun on(methodCall: T.() -> R) = Mockito.`when`(mock.methodCall()) + + fun on(methodCall: T.() -> R, c: KClass): OngoingStubbing { + val r = try { + mock.methodCall() + } catch(e: NullPointerException) { + // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a + // null value for a non-nullable generic type. + // We catch this NPE to return a valid instance. + // The Mockito state has already been modified at this point to reflect + // the wanted changes. + createInstance(c) + } + return Mockito.`when`(r) + } + + inline fun on(noinline methodCall: T.() -> R): OngoingStubbing { + return on(methodCall, R::class) + } } infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing = thenReturn(t) diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index 979c71b2..faa67453 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -54,7 +54,11 @@ interface Methods { fun nullableString(s: String?) fun stringResult(): String - fun builderMethod() : Methods + fun builderMethod(): Methods +} + +interface GenericMethods { + fun genericMethod(): T } class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 723cb374..3db6f1b8 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -436,4 +436,15 @@ class MockitoTest { expect(mock.stringResult()).toBe("a") expect(mock.stringResult()).toBe("b") } + + @Test + fun doReturn_withGenericIntReturnType() { + /* Given */ + val mock = mock> { + on { genericMethod() } doReturn 2 + } + + /* Then */ + expect(mock.genericMethod()).toBe(2) + } } diff --git a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt similarity index 89% rename from mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt rename to mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt index a5abaf8f..47e35211 100644 --- a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt +++ b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt @@ -28,7 +28,7 @@ import org.junit.Test import java.io.IOException import java.math.BigInteger -class CreateInstanceOfImmutableTest { +class CreateInstanceInlineTest { class ClassToBeMocked { @@ -97,6 +97,24 @@ class CreateInstanceOfImmutableTest { } } + @Test + fun createPrimitiveInstance() { + /* When */ + val i = createInstance() + + /* Then */ + expect(i).toBe(0) + } + + @Test + fun createStringInstance() { + /* When */ + val s = createInstance() + + /* Then */ + expect(s).toBe("") + } + interface Methods { fun throwableClass(t: ThrowableClass)