mockk: MockKException: Class cast exception happened while mocking generic class

Expected Behavior

mock class

Current Behavior

every block raise io.mockk.MockKException: Class cast exception happened.

Failure Information (for bugs)

Steps to Reproduce

Preparing

$ git clone https://github.com/ganadist/VersionCodeDemo test -b mockk_cast_exception_robolectric_4.4
$ cd test

On java 8, it has no problem

$ /usr/lib/jvm/java-8-openjdk/bin/java -version
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

$ git checkout origin/mockk_cast_exception_robolectric_4.4~2

### pass with java8 + robolectric 4.3.1 + mockk 1.10.0
$ ./gradlew clean
$ env JAVA_HOME=/usr/lib/jvm/java-8-openjdk ./gradlew :app:testDevelopDebugUnitTest --no-build-cache

$ git checkout origin/mockk_cast_exception_robolectric_4.4~1

### pass with java8 + robolectric 4.4 + mockk 1.10.0
$ ./gradlew clean
$ env JAVA_HOME=/usr/lib/jvm/java-8-openjdk ./gradlew :app:testDevelopDebugUnitTest --no-build-cache

$ git checkout origin/mockk_cast_exception_robolectric_4.4

### pass with java8 + robolectric 4.4 + mockk 1.10.1-SNAPSHOT
$ ./gradlew clean
$ env JAVA_HOME=/usr/lib/jvm/java-8-openjdk ./gradlew :app:testDevelopDebugUnitTest --no-build-cache

On java 11 + Robolectric 4.4, mockk raise io.mockk.MockKException: Class cast exception happened.

$ /usr/lib/jvm/java-11-openjdk/bin/java -version
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10)
OpenJDK 64-Bit Server VM (build 11.0.8+10, mixed mode)

$ git checkout origin/mockk_cast_exception_robolectric_4.4~2

### pass with java11 + robolectric 4.3.1 + mockk 1.10.0
$ ./gradlew clean
$ env JAVA_HOME=/usr/lib/jvm/java-11-openjdk ./gradlew :app:testDevelopDebugUnitTest --no-build-cache

$ git checkout origin/mockk_cast_exception_robolectric_4.4~1

### fail with java11 + robolectric 4.4 + mockk 1.10.0
$ ./gradlew clean
$ env JAVA_HOME=/usr/lib/jvm/java-11-openjdk ./gradlew :app:testDevelopDebugUnitTest --no-build-cache

$ git checkout origin/mockk_cast_exception_robolectric_4.4

### fail with java11 + robolectric 4.4 + mockk 1.10.1-SNAPSHOT
$ ./gradlew clean
$ env JAVA_HOME=/usr/lib/jvm/java-11-openjdk ./gradlew :app:testDevelopDebugUnitTest --no-build-cache

Context

Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.

It seems similar with #321, but this issue is not about chained call.

Failure Logs

https://scans.gradle.com/s/5e26rzx5n36zs/console-log#L38

Stack trace

https://scans.gradle.com/s/5e26rzx5n36zs/tests/:app:testDevelopDebugUnitTest/com.example.myapplication.UnitTest2/test1#1

Minimal reproducible code (the gist of this issue)

https://github.com/ganadist/VersionCodeDemo/blob/mockk_cast_exception_robolectric_4.4/app/src/test/java/com/example/myapplication/UnitTest2.kt#L28-L30

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 9
  • Comments: 17

Most upvoted comments

This is still an issue and I argue that it’s an important one since it affects all modern Android development projects

@Raibaz Why is this issue closed? It keeps crashing in mocck 1.12.0 even with the hint mentioned here https://mockk.io/#chained-calls

since the issue is not resolved yet, could someone tell me what might be the best workaround for this?

Still a problem. Please add the “important” label

The bug is caused because the class loader of the test class (org.robolectric.internal.AndroidSandbox$SdkSandboxClassLoader) and that of JvmAutoHinter (jdk.internal.loader.ClassLoders$AppClassLoader) is different. I think this bug is not occured when JvmAutoHinter use the class loader of test class at Class.forName.

I made the PR about this bug, but my fix may be not a pretty code, so please make additional changes.

Other solution (workaround) is to use hint method like this

every {
    hint(SomeExtensionModule::class)
    SomeExtensionAccess.getExtensionModule()
} returns module

I had this issue and using hint also solved it for me. In my case I had a method which received a generic type and using hint before it apparently made it possible for the JVM to properly identify it. For reference:

every {
    hint(MyClass::class)
    MyConverterClass.someMethod(MyClass::class.java)
} returns mock

I still can experience this issue, does someone here knows a possible solution?

I have same one, but this one is more wired. I passed my tests days ago, but tests failed at this time, even I did not change them. After some checks, I found somehow I used IBM’s JVM (which use OpenJ9 as VM). Hope it helps.

I had this issue and using hint also solved it for me. In my case I had a method which received a generic type and using hint before it apparently made it possible for the JVM to properly identify it. For reference:

every {
    hint(MyClass::class)
    MyConverterClass.someMethod(MyClass::class.java)
} returns module

Where do you get hold of “module”? Or is it supposed to be the return value of the mock?

@alwa yeah, it’s actually mock. Edited the previous comment.

Issue is ongoing with v1.11.0

There are already several issues open about the incompatibility between mockk and robolectric 4.4.

There is some discussion open in the robolectric repo on how to address this, no need to reopen this issue.