Skip to content

Fix #1342: Handle value classes for type parameters and don't unbox value classes returned as interface/supertype#1442

Merged
Raibaz merged 14 commits intomockk:masterfrom
ianbrandt:issue-1342
Jan 19, 2026
Merged

Fix #1342: Handle value classes for type parameters and don't unbox value classes returned as interface/supertype#1442
Raibaz merged 14 commits intomockk:masterfrom
ianbrandt:issue-1342

Conversation

@ianbrandt
Copy link
Contributor

@ianbrandt ianbrandt commented Oct 25, 2025

Handle generic type parameters of value classes. Don't unbox value classes that are returned as their interface or supertype to avoid a ClassCastException. See added KDoc for details. Fixes #1342.

if (!resultType.isValue_safe) {
return this
}

Copy link
Contributor Author

@ianbrandt ianbrandt Oct 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reworked the function to remove duplication and hopefully improve clarity.

.gitignore Outdated

.gradle/

.kotlin/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created by Kotlin Gradle Plugin during tests.

@ianbrandt ianbrandt marked this pull request as draft October 27, 2025 00:52
assertEquals(JavaEnum.A, result)
}

@Test
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added several test cases covering value class handling.

@ianbrandt ianbrandt marked this pull request as ready for review October 27, 2025 05:28
@ianbrandt ianbrandt changed the title Fix #1342: Don't unbox value for value class returned as interface/supertype Fix #1342: Handle value class type parameters and don't unbox value for value class returned as interface/supertype Oct 27, 2025
@ianbrandt ianbrandt changed the title Fix #1342: Handle value class type parameters and don't unbox value for value class returned as interface/supertype Fix #1342: Handle value classes for type parameters and don't unbox value classes returned as interface/supertype Oct 27, 2025
@ianbrandt
Copy link
Contributor Author

I see there was a build failure:

https://github.com/mockk/mockk/actions/runs/18830786451/job/53742959648?pr=1442#step:9:630

I'm not particularly familiar with Android development. Is this something I need to fix in my PR, or an issue with the build infrastructure?

@Raibaz
Copy link
Collaborator

Raibaz commented Oct 28, 2025

@ianbrandt , can you please rebase on top of the master branch? I should have fixed the build failure.

@ianbrandt
Copy link
Contributor Author

ianbrandt commented Oct 29, 2025

can you please rebase on top of the master branch? I should have fixed the build failure.

@Raibaz, Done. Thank you for considering this PR.

Additional notes:

As I dug into this with test cases, I realized the issue I described in #1342 (comment) turned out to be a separate, much simpler to fix bug than the generics issue originally reported by @micheljung. I’ve attempted to fix both in this PR.

Admittedly, not being deeply familiar with MockK or Kotlin value class internals, I leaned on Junie quite a bit to help develop the code and documentation for the cached "*unbox-impl" MethodHandle approach that ultimately got the generic value class tests passing. I did review and refine it, so it’s not just blindly used AI-generated code. That said, I’m not sure whether it's the best possible solution. Feedback welcomed. If there's a more recommended approach regarding MockK’s architecture or long-term Kotlin value class compatibility, I’m happy to take stab at that. I'm also on the fence about the added KDoc and comments. They do explain what's going on, but they're also a bit much. If you want me to pare them down, I can.

@Raibaz
Copy link
Collaborator

Raibaz commented Oct 30, 2025

Thanks for this! I like the test coverage particularly.

I agree the KDoc and comments in ValueClassSupport.kt are a bit too much, can you clean them up a bit?

@ianbrandt
Copy link
Contributor Author

I agree the KDoc and comments in ValueClassSupport.kt are a bit too much, can you clean them up a bit?

You got it. Will do.

@ianbrandt
Copy link
Contributor Author

@Raibaz, I finally got a chance to clean up the KDoc and inline comments for this change. I also rebased the changes onto the latest master (hence the force push to this branch). Let me know if you see anything else that needs fixing.

@Raibaz
Copy link
Collaborator

Raibaz commented Jan 6, 2026

Can you also please run ./gradlew spotlessApply to make the builds pass? 🙏

Thanks!

@ianbrandt
Copy link
Contributor Author

Done. I wasn't familiar with Spotless. I'll be sure to run that after any other changes going forward. Thanks!

@Raibaz
Copy link
Collaborator

Raibaz commented Jan 7, 2026

Looks like there are some test failures in older Kotlin versions and in instrumented tests. Can you PTAL?

Thanks! 🙏

…y version to align with the `io_mockk_kotlin_version` Gradle project property, if set.
…to support backwards compatibility with Android API level 21.
@ianbrandt
Copy link
Contributor Author

ianbrandt commented Jan 19, 2026

Looks like there are some test failures in older Kotlin versions and in instrumented tests. Can you PTAL?

I believe the client test failures with earlier versions of Kotlin were due to them being run with the latest Kotlinx Coroutines version, which is not that backwards compatible. I believe any coEvery in :test-modules:client-tests would've failed, there just wasn't any such coverage previously. I changed the build to use the latest compatible Kotlinx Coroutines version for each Kotlin version. The corresponding coroutinesVersion logic in 'test-modules/client-tests/build.gradle.kts' may be a point of maintenance going forward.

I believe the instrumented tests were failing because they require compatibility with API level 21, and I had used java.lang.invoke.MethodHandle, which only became available from API level 26. I changed to using java.lang.reflect.Method instead. All the check tests still pass. I'm not familiar with how to setup to run connectedCheck locally yet. I'll be watching for whether they pass if you approve the next workflow run.

P.S. I also rebased against current master and checked spotlessApply.

@Raibaz
Copy link
Collaborator

Raibaz commented Jan 19, 2026

Thanks a lot for all the follow ups, this looks very clean now! 🙏

@Raibaz Raibaz merged commit db40a01 into mockk:master Jan 19, 2026
23 checks passed
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.

ClassCastException when stubbing a method that returns T where T is a value class

2 participants