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

Mocking unsigned Kotlin types ends in java.lang.ClassCastException #544

Closed
bio007 opened this issue Dec 3, 2020 · 11 comments · Fixed by #1202
Closed

Mocking unsigned Kotlin types ends in java.lang.ClassCastException #544

bio007 opened this issue Dec 3, 2020 · 11 comments · Fixed by #1202

Comments

@bio007
Copy link

bio007 commented Dec 3, 2020

I'm mocking simple function returning UInt but after that method is executed in the test it crashes with java.lang.ClassCastException.

every { calculator.compute(any()) } returns 23859762u

Expected Behavior

No crash, mocked function returns unsigned number result.

Current Behavior

Exception java.lang.ClassCastException: kotlin.UInt cannot be cast to java.lang.Integer is thrown in case of UInt return type.

Steps to Reproduce

  1. Write mockk every function for a method returning unsigned number like UInt
  2. Call this function in the test
  3. Exception is thrown

Context

  • MockK version: 1.10.0
  • OS: macOS Catalina
  • Kotlin version: 1.3.72
  • JUnit version: 4.12
  • Type of test: unit test

Minimal reproducible code (the gist of this issue)

    every { calculator.compute(any()) } returns 23859762u
    assertEquals(23859762u, calculator.compute(42))
@stale
Copy link

stale bot commented Feb 2, 2021

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.

@stale stale bot added the stale label Feb 2, 2021
@Raibaz Raibaz added important and removed stale labels Feb 2, 2021
@d35h
Copy link

d35h commented Mar 20, 2021

Looks like something not related to mockk itself as mockk calls byte-buddy under the hood and then byte-buddy delegates getting declaration of methods to Class from jdk: ByteBuddy::MethodList::type::getDeclaredMethods, which returns int instead of UInt. I'd say that Kotlin's UInt is not interpolated correctly by this method making UInt as Int

@ianbrandt
Copy link

ianbrandt commented Apr 5, 2021

I ran into what may be the same issue trying to verify behavior on a mock with a method that takes a UShortArray:

interface MyInterface {
    suspend fun myMethod(arg1: UShortArray, arg2: Int, arg3: Int)
}
runBlockingTest {

    val mockMyInterface = mockk<MyInterface>()
    ...
    coVerify {
        mockMyInterface.myMethod(any(), any(), any())
    }
}

The error refers to trying to match a signature with ShortArray instead of UShortArray:

Failed matching mocking signature for
SignedCall(retValue=, isRetValueMock=true, retType=class kotlin.Any, self=MyInterface(#1), method=myMethod-GWzLcNs(ShortArray, Int, Int, Continuation), args=[null, 866937822, -1738456294, Continuation at my.package.MyTest$test my method$1$1.invokeSuspend(MyTest.kt:10)], invocationStr=MyInterface(#1).myMethod-GWzLcNs(null, 866937822, -1738456294, continuation {}))
left matchers: [any()]

@Raibaz
Copy link
Collaborator

Raibaz commented Apr 6, 2021

Unsigned integer support in Kotlin is still in beta, so I guess @d35h is right.

@Kantis
Copy link

Kantis commented Jun 10, 2021

I guess #633 might resolve this, since unsigned types are implemented using value classes

@nosideeffects
Copy link

Does not look like #633 solved this issue. Any idea the scope of work to get this to work?

@migueltorcha
Copy link

migueltorcha commented Jan 12, 2022

Same issue here trying to mock a UByte:

interface MyInterface {
  suspend fun myMethod(): UByte?
}

....

coEvery { myInterface.myMethod() } returns Random.nextInt().toUByte()

As result, I have the next:
class java.lang.Byte cannot be cast to class kotlin.UByte (java.lang.Byte is in module java.base of loader 'bootstrap'; kotlin.UByte is in unnamed module of loader 'app') java.lang.ClassCastException: class java.lang.Byte cannot be cast to class kotlin.UByte (java.lang.Byte is in module java.base of loader 'bootstrap'; kotlin.UByte is in unnamed module of loader 'app')

@cdprete
Copy link

cdprete commented Jan 18, 2023

I do have the same issue even with version 1.12.5 on a @RelaxedMockK with a UInt nullable field.

@cdprete
Copy link

cdprete commented Jan 23, 2023

I can confirm the same issue is present even with version 1.13.3 and Kotlin 1.8

@zTrap
Copy link

zTrap commented Oct 24, 2023

Problem still here. mockk 1.13.8, kotlin 1.9.10

@brian-livefront
Copy link

This issue still seems to be present on 1.13.10. See #1226

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants