mockk: Bug: ClassCastException when using relaxed mock of generic type

Prerequisites

Please answer the following questions for yourself before submitting an issue.

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Description

I might have run into a MockK limitation trying to use relaxed mock of a generic type (particularly Spring’s JpaRepository). When using such mock object, my test throws a ClassCastException at the point where the test code calls the method of the mock object that returns an object using the type parameter.

For example, if have the following types,

interface BaseRepository<T> {
    fun save(obj: T): T
}

interface BookRepository: BaseRepository<Book>

and I declare a relaxed mock for BookRepository, the test throws a ClassCastException during the invocation of save(book).

Steps to Reproduce

I have prepared a demo code base to illustrate this issue. Please check the last 3-4 commits as I experimented a bit to confirm that this issue doesn’t only affect Spring’s JpaRepository but in general, any type (interface) with similar declaration.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 39
  • Comments: 22

Most upvoted comments

I am facing the same issue. I am using a Result wrapper for my network models.

sealed class Result<out R> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Failure) : Result<Nothing>()
}

However, I am getting;

java.lang.ClassCastException: java.lang.Object cannot be cast to mypath.data.MyResponse

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.

Not able to mock repository beans, get this error with save calls. Tried to use hint and relaxed, still same problem.

I solved it as below every { repository.save<ReturnTypecClass>(any()) } returns ReturnTypeClass

Any updates on this by any chance? I have hundreds of tests failing because of this issues so unfortunately using hint() on all of them would be an enormous effort. Type inference was somehow working on Java 8 (I only have this issue when switching to Java 11). This is possibly related to https://github.com/mockk/mockk/issues/606 as well?

As it is quite common to test with the JpaRepository pattern, this issue is quite impactful.

same problem here (mockk 1.9.3). Small example code to reproduce the problem:

interface BaseRepository<T> {
    fun save(obj: T): T
}

interface IntRepository: BaseRepository<Int>

fun main(args: Array<String>) {
    val a = mockk<IntRepository>(relaxed = true)
    a.save(1)
}

Results in:

Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.Integer