mockito: Can't mock on Android for Kotlin even I already mark everything as open

First I got error with something can’t mock final class. Then I mark the class as open even for private property. But then I got a similar error with different text: Mockito can only mock non-private & non-final classes.

This is the generated code.

package nz.salect.kmoblib.ui.helpers

public open class AuthHelper public constructor(userPreference: nz.salect.kmoblib.store.UserPreference, deviceId: nz.salect.kotlinidiom.utils.DeviceId, authService: nz.salect.kmoblib.services.AuthService) {
    public open val authService: nz.salect.kmoblib.services.AuthService /* compiled code */

    public open val deviceId: nz.salect.kotlinidiom.utils.DeviceId /* compiled code */

    public open val userPreference: nz.salect.kmoblib.store.UserPreference /* compiled code */

    public open fun generateSMS(quickName: kotlin.String, password: kotlin.String): kotlin.String { /* compiled code */ }

    public open fun logDetails(registerData: kotlin.collections.Map<kotlin.String, kotlin.String>): nz.salect.kotlinidiom.http.HttpResponse { /* compiled code */ }

    public open fun login(loginData: kotlin.collections.Map<kotlin.String, kotlin.String>): nz.salect.kotlinidiom.http.HttpResponse { /* compiled code */ }

    public open fun startBrowsing(): nz.salect.kotlinidiom.http.HttpResponse { /* compiled code */ }
}

This is mockito in my build.gradle, I only use it for espresso ui test

androidTestImplementation "org.mockito:mockito-core:2.18.0"
androidTestImplementation "org.mockito:mockito-android:2.18.0"

This is the test

@SmallTest
@RunWith(AndroidJUnit4::class)
class EntryUITest {

    @Rule
    @JvmField
    val rule = espressoDaggerMockRule()

    @Rule
    @JvmField
    val entryAuthActivityRule = ActivityTestRule(EntryActivity::class.java,false,false)

    val authHelper = mock(AuthHelper::class.java)
}

val authHelper = mock(AuthHelper::class.java) this line is where it throws exception

This is error message


org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class nz.salect.kmoblib.ui.helpers.AuthHelper.

Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.



IMPORTANT INFORMATION FOR ANDROID USERS:

The regular Byte Buddy mock makers cannot generate code on an Android VM!
To resolve this, please use the 'mockito-android' dependency for your application:
http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22mockito-android%22%20g%3A%22org.mockito%22

Java               : 0.9
JVM vendor name    : The Android Project
JVM vendor version : 2.1.0
JVM name           : Dalvik
JVM version        : 0.9
JVM info           : null
OS name            : Linux
OS version         : 3.10.0+


Underlying exception : java.lang.IllegalArgumentException: Could not create type
at nz.salect.handset.auth.EntryUITest.<init>(EntryUITest.kt:35)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at android.support.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:101)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:385)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
Caused by: java.lang.IllegalArgumentException: Could not create type
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:139)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:345)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:160)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:354)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:32)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMockType(SubclassByteBuddyMockMaker.java:71)
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:42)
at org.mockito.android.internal.creation.AndroidByteBuddyMockMaker.createMock(AndroidByteBuddyMockMaker.java:39)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:65)
at org.mockito.Mockito.mock(Mockito.java:1875)
at org.mockito.Mockito.mock(Mockito.java:1784)
... 29 more
Caused by: java.lang.IncompatibleClassChangeError: The method 'int java.lang.Object.hashCode()' was expected to be of type interface but instead was found to be of type virtual (declaration of 'net.bytebuddy.dynamic.scaffold.MethodRegistry$Handler$ForImplementation' appears in /data/app/nz.salect.handset.test-1/base.apk)
at net.bytebuddy.dynamic.scaffold.MethodRegistry$Handler$ForImplementation.hashCode(MethodRegistry.java)
at sun.misc.Hashing.singleWordWangJenkinsHash(Hashing.java:48)
at java.util.HashMap.put(HashMap.java:423)
at java.util.HashSet.add(HashSet.java:217)
at net.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:409)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:162)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:155)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2669)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2771)
at org.mockito.internal.creation.bytebuddy.SubclassBytecodeGenerator.mockClass(SubclassBytecodeGenerator.java:123)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:37)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:34)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:137)
... 40 more

Anything I am missing here? Seems this is somegthing which shouldn’t happen

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 16 (5 by maintainers)

Most upvoted comments

Found my issue. With declaring regular mockito for vanilla junit tests, and mockito-android for instrumentation tests, I was getting a duplicate file error on mockito-extensions/org.mockito.plugins.MockMaker, which I was excluding (whoops). I changed my packaging options to this to fix it:

packagingOptions {
    pickFirst 'mockito-extensions/org.mockito.plugins.MockMaker'
}

Experiencing the same thing with:

testImplementation 'org.mockito:mockito-core:2.18.3'
androidTestImplementation 'org.mockito:mockito-android:2.18.3'

Doesn’t matter if it’s a Kotlin class or Java class, same result.

Tomorrow I’m going to try it on a new project to see if I get the same results.