From f1a638e7ecaa21842131d49b14b4518649e59c76 Mon Sep 17 00:00:00 2001 From: "Stuebinger, Bernd" Date: Wed, 7 Sep 2022 11:24:43 +0200 Subject: [PATCH] Properly handle sealed classes with Kotlin 1.7 and JDK 17 --- .../kotlin/io/mockk/proxy/jvm/ProxyMaker.kt | 15 +++++++++++---- .../kotlin/io/mockk/it/SealedClassTest.kt | 3 --- .../kotlin/io/mockk/it/SealedInterfaceTest.kt | 3 --- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/ProxyMaker.kt b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/ProxyMaker.kt index 39c7a5fec..0a05d3536 100644 --- a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/ProxyMaker.kt +++ b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/ProxyMaker.kt @@ -99,18 +99,25 @@ internal class ProxyMaker( clazz: Class, interfaces: Array> ): Class { - return if (Modifier.isFinal(clazz.modifiers)) { + val kClass = clazz.kotlin + return if (kClass.isFinal) { log.trace("Taking instance of $clazz itself because it is final.") clazz - } else if (interfaces.isEmpty() && !Modifier.isAbstract(clazz.modifiers) && inliner != null) { + } else if (interfaces.isEmpty() && !kClass.isAbstract && inliner != null) { log.trace("Taking instance of $clazz itself because it is not abstract and no additional interfaces specified.") clazz + } else if (kClass.isSealed) { + log.trace("Taking instance of subclass of $clazz because it is sealed.") + kClass.sealedSubclasses.firstNotNullOfOrNull { + @Suppress("UNCHECKED_CAST") + subclass(it.java, interfaces) as Class + } ?: error("Unable to create proxy for sealed class $clazz, available subclasses: ${kClass.sealedSubclasses}") } else { log.trace( "Building subclass proxy for $clazz with " + "additional interfaces ${interfaces.toList()}" ) - subclasser.subclass(clazz, interfaces) + subclasser.subclass(clazz, interfaces) } } @@ -143,7 +150,7 @@ internal class ProxyMaker( val defaultConstructor = cls.getDeclaredConstructor() try { defaultConstructor.isAccessible = true - } catch (ex: Exception) { + } catch (ignored: Exception) { // skip } diff --git a/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedClassTest.kt b/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedClassTest.kt index f48c8b1f4..efa39cab2 100644 --- a/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedClassTest.kt +++ b/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedClassTest.kt @@ -2,7 +2,6 @@ package io.mockk.it import io.mockk.every import io.mockk.mockk -import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals @@ -10,7 +9,6 @@ import kotlin.test.assertEquals class SealedClassTest { @Test - @Ignore("Fails on JDK17+ https://github.com/mockk/mockk/issues/832") fun serviceReturnsSealedClassImpl() { val factory = mockk { every { create() } returns Leaf(1) @@ -22,7 +20,6 @@ class SealedClassTest { } @Test - @Ignore("Fails on JDK17+ https://github.com/mockk/mockk/issues/832") fun serviceAnswersSealedClassImpl() { val factory = mockk { every { create() } answers { Leaf(1) } diff --git a/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedInterfaceTest.kt b/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedInterfaceTest.kt index 4abe70221..91f727abf 100644 --- a/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedInterfaceTest.kt +++ b/modules/mockk/src/commonTest/kotlin/io/mockk/it/SealedInterfaceTest.kt @@ -3,14 +3,12 @@ package io.mockk.it import io.mockk.every import io.mockk.mockk import kotlin.test.Test -import kotlin.test.Ignore import kotlin.test.assertEquals class SealedInterfaceTest { @Test - @Ignore("Fails on JDK17+ https://github.com/mockk/mockk/issues/832") fun serviceReturnsSealedClassImpl() { val factory = mockk { every { create() } returns Leaf(1) @@ -22,7 +20,6 @@ class SealedInterfaceTest { } @Test - @Ignore("Fails on JDK17+ https://github.com/mockk/mockk/issues/832") fun serviceAnswersSealedClassImpl() { val factory = mockk { every { create() } answers { Leaf(1) }