Skip to content

Conversation

VasilisDrettas-tomtom
Copy link
Contributor

Fix #813

Problem:
When trying to mock a function that returns a nullable value class, a ClassCastException was thrown. Thats because mockk is using the boxedClass. Nullable value classes should be handled differently because they are not inlined.

For example
Caused by: java.lang.ClassCastException: class java.lang.Integer cannot be cast to class io.mockk.it.ValueClassTest$Companion$DummyValue (java.lang.Integer is in module java.base of loader 'bootstrap'; io.mockk.it.ValueClassTest$Companion$DummyValue is in unnamed module of loader 'app')

Implementation:
When the return type of the function or a member property is nullable do not use the boxedClass but use the value class itself

Fix mockk#813

Problem:
When trying to mock a function that returns a nullable value class, a ClassCastException was thrown. Thats because  mockk is using the boxedClass.
Nullable value classes should be handled differently because they are not inlined.

Implementation:
When the return type of the function or a member property is nullable do not use the boxedClass but use the value class itself

fix
@Raibaz Raibaz merged commit 7148465 into mockk:master Sep 12, 2024
19 checks passed
@Raibaz
Copy link
Collaborator

Raibaz commented Sep 12, 2024

Thanks for looking into this!

@dadadom
Copy link

dadadom commented Oct 10, 2024

I think this might have broken some of my testcases which worked with 1.13.12.

    @JvmInline
    private value class MyId(private val id: String)

    private interface Y {
        suspend fun getId(): MyId?
    }

    private class X(private val y: Y) {
        suspend fun doStuff(): MyId? = y.getId()
    }

    @Test
    fun `test stuff`() {
        val mocked = mockk<Y>()
        coEvery { mocked.getId() } returns MyId("987")

        runBlocking { X(mocked).doStuff() } shouldBe MyId("987")
    }

Error message:

12:26:43.893 [Test worker] DEBUG io.mockk.impl.instantiation.AbstractMockFactory -- Creating mockk for Y name=#1
12:26:44.895 [Test worker @coroutine#4] DEBUG io.mockk.impl.recording.states.AnsweringState -- Answering MyId(id=987) on Y(#1).getId-oOl4dpc(continuation {})

class MyTest$MyId cannot be cast to class java.lang.String (MyTest$MyId is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
java.lang.ClassCastException: class MyTest$MyId cannot be cast to class java.lang.String (MyTest$MyId is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
	at MyTest$X.doStuff-oOl4dpc(MyTest.kt:17)
	at MyTest$test stuff$2.invokeSuspend(MyTest.kt:25)
...

@VasilisDrettas-tomtom
Copy link
Contributor Author

You are right @dadadom, it seems to be a regression due to my change. I will attempt to fix the regression once I find sometime.

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

Successfully merging this pull request may close these issues.

Cannot mock function returning nullable value class
3 participants