Skip to content

Kotlin - Unable to return value classes #456

Open
@kargath

Description

@kargath

When returning a value class from a mocked method, class cast can not be done properly

Sample code:

value class Base64Data(val data: String)
fun doSomething(data: Base64Data): Base64Data = Base64Data("test")

/**
 * Workaround to support matching of value classes
 *
 * From: https://github.com/mockito/mockito-kotlin/issues/445#issuecomment-983619131
 */
inline fun <Outer, reified Inner> eqValueClass(
    expected: Outer,
    crossinline access: (Outer) -> Inner,
    test: ((actual: Any) -> Boolean) -> Any? = ::argWhere
): Outer {
    val assertion: (Any) -> Boolean = { actual ->
        if (actual is Inner) {
            access(expected) == actual
        } else {
            expected == actual
        }
    }
    @Suppress("UNCHECKED_CAST")
    return test(assertion) as Outer? ?: expected
}

    @Test
    fun `test something`() = runTest {
        // GIVEN
        val screenshotEncoded = Base64Data("screenshot-encoded")
        whenever(
            client.doSomething(
               eqValueClass(levelData, { it.data })
            )
        ) doReturn screenshotEncoded

        // WHEN
        {...}
}

When executing that code and getting the mock the response is as follows:

java.lang.ClassCastException: class com.king.uplevelmanager.util.Base64Data cannot be cast to class java.lang.String (com.king.uplevelmanager.util.Base64Data is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')

Tested returning a simple type like String (to discard matcher failing) and worked successfully.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions