lupuuss / Mokkery

The mocking library for Kotlin Multiplatform, easy to use, boilerplate-free and compiler plugin driven.
https://mokkery.dev
Apache License 2.0
201 stars 8 forks source link

`KClass for Objective-C classes is not supported yet` when using platform classes in mocks #43

Closed casvanluijtelaar closed 1 month ago

casvanluijtelaar commented 1 month ago

When using a parameter which reference a common interface of a plarform type the following error is thrown:

kotlin.IllegalStateException: KClass for Objective-C classes is not supported yet
    at kotlin.Throwable#<init>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt:28)
    at kotlin.Exception#<init>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:23)
    at kotlin.RuntimeException#<init>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:34)
    at kotlin.IllegalStateException#<init>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:70)
    at kotlin.native.internal.KClassUnsupportedImpl#<get-qualifiedName>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KClassImpl.kt:66)
    at kotlin.reflect.KClass#<get-qualifiedName>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/reflect/KClass.kt:27)
    at dev.mokkery.internal#bestName__at__kotlin.reflect.KClass<*>(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/nativeMain/kotlin/dev/mokkery/internal/Utils.native.kt:5)
    at dev.mokkery.internal.signature.SignatureGeneratorImpl.generate$lambda$0#internal(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/signature/SignatureGenerator.kt:16)
    at dev.mokkery.internal.signature.SignatureGeneratorImpl.$generate$lambda$0$FUNCTION_REFERENCE$0.invoke#internal(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/signature/SignatureGenerator.kt:16)
    at kotlin.Function1#invoke(/Users/casvanluijtelaar/.gradle/daemon/8.7/[K][Suspend]Functions:1)
    at kotlin.text#appendElement__at__kotlin.text.Appendable(/opt/buildAgent/work/ed783494cd2364bc/kotlin/libraries/stdlib/src/kotlin/text/Appendable.kt:84)
    at kotlin.collections#joinTo__at__kotlin.collections.Iterable<0:0>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/libraries/stdlib/common/src/generated/_Collections.kt:3493)
    at kotlin.collections#joinToString__at__kotlin.collections.Iterable<0:0>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/libraries/stdlib/common/src/generated/_Collections.kt:3510)
    at kotlin.collections#joinToString$default__at__kotlin.collections.Iterable<0:0>(/opt/buildAgent/work/ed783494cd2364bc/kotlin/libraries/stdlib/common/src/generated/_Collections.kt:3509)
    at dev.mokkery.internal.signature.SignatureGeneratorImpl#generate(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/signature/SignatureGenerator.kt:16)
    at dev.mokkery.internal.signature.SignatureGenerator#generate(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/signature/SignatureGenerator.kt:7)
    at dev.mokkery.internal.templating.TemplatingScopeImpl.saveTemplate#internal(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/templating/TemplatingScope.kt:120)
    at dev.mokkery.internal.templating.TemplatingScope#saveTemplate(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/templating/TemplatingScope.kt:32)
    at dev.mokkery.internal.templating.TemplatingMokkeryInterceptorImpl.interceptCall#internal(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/templating/TemplatingInterceptor.kt:46)
    at dev.mokkery.internal.MokkeryInterceptor#interceptCall(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/MokkeryInterceptor.kt:10)
    at dev.mokkery.internal.CombinedInterceptor.interceptCall#internal(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/MokkeryInterceptor.kt:32)
    at dev.mokkery.internal.MokkeryInterceptor#interceptCall(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/MokkeryInterceptor.kt:10)
    at dev.mokkery.internal.MokkeryMockImpl.interceptCall#internal(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/MokkeryMock.kt:1)
    at dev.mokkery.internal.MokkeryInterceptor#interceptCall(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/MokkeryInterceptor.kt:10)
    at com.x.lib.dateformatter.NestedInterfaceMockb3e0512b1b5d4d7b8c50198106831e2a#nestedTestMethod(/Users/casvanluijtelaar/Projects/x-gmalite-multiplatform/x-date-formatter-lib/src/commonTest/kotlin/com/x/lib/dateformatter/TextMokkery.kt:8)
    at com.x.lib.dateformatter.NestedInterface#nestedTestMethod(/Users/casvanluijtelaar/Projects/x-gmalite-multiplatform/x-date-formatter-lib/src/commonTest/kotlin/com/x/lib/dateformatter/TextMokkery.kt:8)
    at com.x.lib.dateformatter.testPlatformInCommon$lambda$0#internal(/Users/casvanluijtelaar/Projects/x-gmalite-multiplatform/x-date-formatter-lib/src/commonTest/kotlin/com/x/lib/dateformatter/TextMokkery.kt:30)
    at com.x.lib.dateformatter.$testPlatformInCommon$lambda$0$FUNCTION_REFERENCE$0.invoke#internal(Unknown Source)
    at com.x.lib.dateformatter.$testPlatformInCommon$lambda$0$FUNCTION_REFERENCE$0.$<bridge-DNNN>invoke(Unknown Source)
    at kotlin.Function1#invoke(/Users/casvanluijtelaar/.gradle/daemon/8.7/[K][Suspend]Functions:1)
    at dev.mokkery.internal#internalBaseVerify(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/Verify.kt:45)
    at dev.mokkery.internal#internalVerify(/Users/damianbaczynski/IdeaProjects/Mokkery/mokkery-runtime/src/commonMain/kotlin/dev/mokkery/internal/Verify.kt:41)
    at com.x.lib.dateformatter#testPlatformInCommon(/Users/casvanluijtelaar/Projects/x-gmalite-multiplatform/x-date-formatter-lib/src/commonTest/kotlin/com/x/lib/dateformatter/TextMokkery.kt:31)
    at com.x.lib.dateformatter.$testPlatformInCommon$FUNCTION_REFERENCE$1.invoke#internal(/Users/casvanluijtelaar/Projects/x-gmalite-multiplatform/x-date-formatter-lib/src/commonTest/kotlin/com/x/lib/dateformatter/TextMokkery.kt:19)
    at com.x.lib.dateformatter.$testPlatformInCommon$FUNCTION_REFERENCE$1.$<bridge-DNN>invoke(/Users/casvanluijtelaar/Projects/x-gmalite-multiplatform/x-date-formatter-lib/src/commonTest/kotlin/com/x/lib/dateformatter/TextMokkery.kt:19)
    at kotlin.Function0#invoke(/Users/casvanluijtelaar/.gradle/daemon/8.7/[K][Suspend]Functions:1)
    at kotlin.native.internal.test.TopLevelSuite.TestCase#doRun(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt:240)
    at kotlin.native.internal.test.TestCase#doRun(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt:44)
    at kotlin.native.internal.test.TestCase#run(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt:52)
    at kotlin.native.internal.test.TestCase#run(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt:49)
    at kotlin.native.internal.test.TestRunner.run#internal(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:263)
    at kotlin.native.internal.test.TestRunner.runIteration#internal(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:289)
    at kotlin.native.internal.test.TestRunner#run(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:304)
    at kotlin.native.internal.test#testLauncherEntryPoint(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:33)
    at kotlin.native.internal.test#main(/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:38)
    at <global>.Konan_start(/Users/casvanluijtelaar/.gradle/daemon/8.7/entryPointOwner:1)
    at <global>.Init_and_run_start(Unknown Source)
    at <global>.0x0(Unknown Source)
    at <global>.0x0(Unknown Source)
    at <global>.0x0(Unknown Source)

easy to reproduce in a KMP project:

commonTest

interface NestedInterface {
    fun nestedTestMethod(platformError: TestPlatformError)
}

class TestClass(
    private val nestedTestInterface: NestedInterface,
) {
    fun testMethod(platformError: TestPlatformError) {
        nestedTestInterface.nestedTestMethod(platformError)
    }
}

@Test
fun testPlatformInCommon() {
    // given
    val mock = mock<NestedInterface>()
    val error = createTestPlatformError()
    val testClass = TestClass(mock)

    // when
    testClass.testMethod(error)

    // then
    verify { mock.nestedTestMethod(error) }
}

expect fun createTestPlatformError(): TestPlatformError
expect class TestPlatformError

iosTest

actual typealias TestPlatformError = NSError

actual fun createTestPlatformError(): TestPlatformError {
    return NSError()
}

androidUnitTests

actual typealias TestPlatformError = Throwable

actual fun createTestPlatformError(): TestPlatformError {
    return Throwable()
}

The verify call causes the fail

lupuuss commented 1 month ago

I was able to reproduce it. I should be able to fix and release it this week. Thank you for reporting the issue!

lupuuss commented 1 month ago

Fixed in 2.4.0

casvanluijtelaar commented 1 month ago

can confirm fixed!