Mockk: Bug: spyk for overridden method with generic argument

Created on 1 Jun 2018  路  6Comments  路  Source: mockk/mockk

I want to use spyk for class with generic. It produces StackOverflowError. It is impossible to use every { childClazz.foobar(view) } just Runs and super.foobar(view) definitely need to be invoked

Stack trace

java.lang.StackOverflowError
    at java.lang.Class.getDeclaredMethod(Class.java:2127)
    at java.lang.Object.equals(Object.java:149)
    at kotlin.jvm.internal.Intrinsics.areEqual(Intrinsics.java:164)
    at kotlin.reflect.jvm.internal.KClassCacheKt.getOrCreateKotlinClass(kClassCache.kt:36)
    at kotlin.reflect.jvm.internal.ReflectionFactoryImpl.getOrCreateKotlinClass(ReflectionFactoryImpl.java:45)
    at kotlin.jvm.internal.Reflection.getOrCreateKotlinClass(Reflection.java:61)
    at kotlin.jvm.JvmClassMappingKt.getKotlinClass(JvmClassMapping.kt:91)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper.toDescription(JvmMockFactoryHelper.kt:55)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper.access$toDescription(JvmMockFactoryHelper.kt:13)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invoke(JvmMockFactoryHelper.kt:17)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invoke(JvmMockFactoryHelper.kt:13)
    at io.mockk.impl.instantiation.JvmMockFactoryKt$sam$MockKInvocationHandler$4dff1f07.invocation(JvmMockFactory.kt)
    at io.mockk.proxy.MockKCallProxy.call(MockKCallProxy.java:24)
    at com.app.ChildClazz.foobar(SimpleTest.kt:62)
    at com.app.ChildClazz.foobar(SimpleTest.kt:55)
    at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

Minimal reproducible code (the gist of this issue)

class SpyTest{
    @Test
    fun  callFoobar(){
        val view = mockk<SomeView>()
        val childClazz = spyk(ChildClazz(), recordPrivateCalls = true)
        childClazz.foobar(view)
        assertk.assert(childClazz.called).isEqualTo(true)
    }
}

private interface ParentView

private interface SomeView : ParentView

private interface ParentInterface<V : ParentView> {

    fun foobar(view: V)
}

private abstract class ParentClazz<V : ParentView> : ParentInterface<V> {

    override fun foobar(view: V) {

    }
}

private class ChildClazz : ParentClazz<SomeView>() {

    var called: Boolean = false

    override fun foobar(view: SomeView) {
        super.foobar(view)
        called = true
    }
} 
bug important

All 6 comments

Issue is bridge method handling:

  // access flags 0x1
  public foobar(Labc/Sub;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    ALOAD 1
    LDC "view"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
   L1
    LINENUMBER 29 L1
    ALOAD 0
    ALOAD 1
    CHECKCAST abc/Base
    INVOKESPECIAL abc/ParentClazz.foobar (Labc/Base;)V
   L2
    LINENUMBER 30 L2
    ALOAD 0
    ICONST_1
    PUTFIELD abc/ChildClazz.called : Z
   L3
    LINENUMBER 31 L3
    RETURN
   L4
    LOCALVARIABLE this Labc/ChildClazz; L0 L4 0
    LOCALVARIABLE view Labc/Sub; L0 L4 1
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x1041
  public synthetic bridge foobar(Labc/Base;)V
   L0
    LINENUMBER 25 L0
    ALOAD 0
    ALOAD 1
    CHECKCAST abc/Sub
    INVOKEVIRTUAL abc/ChildClazz.foobar (Labc/Sub;)V
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 2

Need some time to analyze and fix it.

I have an approach to resolve it. But it requires quite serious changes as seems byte buddy doesn't support calling "super" methods. Checking that here: https://github.com/raphw/byte-buddy/issues/483

Hi there, any news about this bug?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale just ask to put an important label.

This is definitely a blocking one for me

Any updates for now?

Was this page helpful?
0 / 5 - 0 ratings