Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kover breaks mocking OkHttp's Response with MockK #88

Closed
cristan opened this issue Dec 7, 2021 · 9 comments
Closed

Kover breaks mocking OkHttp's Response with MockK #88

cristan opened this issue Dec 7, 2021 · 9 comments
Labels
Bug Bug issue type Kover Coverage Tool S: postponed Status: work on the issue is not in the short term plans

Comments

@cristan
Copy link

cristan commented Dec 7, 2021

Tested on Kover 0.4.4:

plugins {
    id 'org.jetbrains.kotlinx.kover' version '0.4.4'
}

Dependencies:

implementation 'com.squareup.okhttp3:okhttp:4.9.1'
testImplementation "io.mockk:mockk:1.12.1"

Tests:

@Test
fun testMockingRequest() {
    val response: Request = mockk()
}

@Test
fun testMockingResponse() {
    val response: Response = mockk()
}

testMockingResponse() fails here with this stacktrace:

java.lang.VerifyError
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
	at io.mockk.proxy.jvm.transformation.JvmInlineInstrumentation.retransform(JvmInlineInstrumentation.kt:28)
	at io.mockk.proxy.common.transformation.RetransformInlineInstrumnetation$execute$1.invoke(RetransformInlineInstrumnetation.kt:19)
	at io.mockk.proxy.common.transformation.RetransformInlineInstrumnetation$execute$1.invoke(RetransformInlineInstrumnetation.kt:6)
	at io.mockk.proxy.common.transformation.ClassTransformationSpecMap.applyTransformation(ClassTransformationSpecMap.kt:41)
	at io.mockk.proxy.common.transformation.RetransformInlineInstrumnetation.execute(RetransformInlineInstrumnetation.kt:16)
	at io.mockk.proxy.jvm.ProxyMaker.inline(ProxyMaker.kt:88)
	at io.mockk.proxy.jvm.ProxyMaker.proxy(ProxyMaker.kt:30)
	at io.mockk.impl.instantiation.JvmMockFactory.newProxy(JvmMockFactory.kt:34)
	at io.mockk.impl.instantiation.AbstractMockFactory.newProxy$default(AbstractMockFactory.kt:29)
	at io.mockk.impl.instantiation.AbstractMockFactory.mockk(AbstractMockFactory.kt:59)
	at com.example.testkoverandroidproject.ExampleUnitTest.testMockingResponse(ExampleUnitTest.kt:73)

This doesn't happen when I don't add Kover as a plugin. Surprisingly enough, testMockingRequest() always succeeds, so there's something in in mocking Response which goes wrong which doesn't happen when mocking Request.

@shanshin
Copy link
Collaborator

shanshin commented Dec 9, 2021

Hi,
to eliminate the conflict between the MockK and the Kover, try to add all OkHttp classes to the instrumentation exclusions

    testOptions {
        unitTests.all {
            kover {
                excludes = ['okhttp3\\..+']
            }
        }
    }

@shanshin shanshin added the S: waiting for clarification Status: additional information required to proceed label Dec 9, 2021
@cristan
Copy link
Author

cristan commented Dec 14, 2021

It's a little weird that this is needed, but excluding OkHttp classes indeed works.

@cristan
Copy link
Author

cristan commented Jan 17, 2022

Another instance where mocking okhttp stuff is broken by kover:

@Test
fun `test mocking proceeding a chain`() {
    val testChain = mockk<Interceptor.Chain>()
    val argument = slot<Request>()
    every { testChain.proceed(capture(argument)) }.returns(mockk())
}

This gives this error:

java.lang.VerifyError
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
	at io.mockk.proxy.jvm.transformation.JvmInlineInstrumentation.retransform(JvmInlineInstrumentation.kt:28)

Even excluding all okhttp classes doesn't resolve this issue (tested on Kover 0.5.0-RC2).

@foo4u
Copy link

foo4u commented Feb 18, 2022

@shanshin, your recommended workaround isn't working with Kover 0.5.0. After trying different patterns, I switched the coverage engine to JACOCO and it works. The issue seems to be with the kotlinx.kover.api.CoverageEngine.INTELLIJ, which is the default.

Here's all I added to my build.gradle.kts that fixed it:

kover {
    coverageEngine.set(kotlinx.kover.api.CoverageEngine.JACOCO)
}

Does swapping the coverage engine basically make Kover no more useful than using JACOCO directly?

@shanshin
Copy link
Collaborator

@foo4u, in version 0.5.0, the format of filters for classes has changed. Now, instead of specifying a regular expression, you can use only wildcards * and ?.
Therefore, now you can exclude OkHttp from instrumentation like this:

    testOptions {
        unitTests.all {
            kover {
                excludes = ['okhttp3.*']
            }
        }
    }

@louiseightsix
Copy link

Thanks for providing a workaround; this is affecting us as well - would love to get to the bottom of it.

@wezley98
Copy link

Can confirm this also happens to us with the following config on 0.5.1

kover {
    jacocoEngineVersion.set("0.8.8")
    generateReportOnCheck = true
    disabledProjects = setOf(":di", ":icons", ":test")
    instrumentAndroidPackage = false
    runAllTestsForProjectTask = false
}

Can confirm workaround is still working for 0.5.1. Kotlin DSL fix, for anybody not using groovy:

android {
......
testOptions {
        unitTests.all {
            it.extensions.configure(kotlinx.kover.api.KoverTaskExtension::class) {
                excludes = listOf("okhttp3.*")
            }
        }
    }
}

@shanshin shanshin added S: postponed Status: work on the issue is not in the short term plans and removed S: waiting for clarification Status: additional information required to proceed labels Oct 27, 2022
@shanshin
Copy link
Collaborator

There are two ways to avoid this problem:

  • exclude specific libraries from the instrumentation by hardcode their packages - in this case, we do not know in advance which libraries cause problems during instrumentation, and errors will be repeated.
  • exclude from instrumentation all classes that are not included in the user project

@shanshin
Copy link
Collaborator

Closed in favor of #418

@shanshin shanshin closed this as not planned Won't fix, can't repro, duplicate, stale Sep 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Bug issue type Kover Coverage Tool S: postponed Status: work on the issue is not in the short term plans
Projects
None yet
Development

No branches or pull requests

5 participants