Skip to content

fix: normalize value class arguments in EqMatcher for consistent comparison#1440

Merged
Raibaz merged 1 commit intomockk:masterfrom
edwardmp:master
Oct 24, 2025
Merged

fix: normalize value class arguments in EqMatcher for consistent comparison#1440
Raibaz merged 1 commit intomockk:masterfrom
edwardmp:master

Conversation

@edwardmp
Copy link
Contributor

The eq() (and refEq()) matcher fails when comparing value classes, resulting in "no answer found" errors when MockK cannot match configured answers to actual method calls.

Symptom:

MockKException: no answer found for DummyService(#18).argValueClassReturnValueClass-fKa6D0c(101) 
among the configured answers: (DummyService(#18).argValueClassReturnValueClass-fKa6D0c(refEq(DummyValue(value=101))))

Root Cause:

  • Expected value (passed to eq()): Created at test time as a value class wrapper, stored in the matcher before JVM erasure occurs
  • Actual value (method argument): Already erased to its underlying type by the JVM when it reaches the matcher

This creates a type mismatch where we're comparing:

  • Expected: DummyValue wrapper containing 101
  • Actual: Raw Int value 101

The comparison fails because deepEquals(101, DummyValue(101)) returns false.

Solution:

Extract the boxed (underlying) value from the expected value class when creating the EqMatcher, ensuring both sides of the comparison use the same representation.

Changes:

  • Modified EqMatcher to call .boxedValue on both the actual arg and comarpsion value
  • This normalizes the expected value to its underlying representation, matching what the JVM provides for the actual argument

Without this fix, the newly added tests in ValueClassTest.kt fail with "no answer found" errors.

I'm not 100% certain this is the optimal location for this fix. The fix works but I'd appreciate input on whether this normalization should happen elsewhere in the matching pipeline or if there's a more appropriate architectural approach for handling value class comparisons.

The fix is backward compatible since boxedValue returns the original object unchanged when called on non-value classes.

…arison

Extract boxed values from value class arguments in EqMatcher
to ensure both expected and actual values are compared at the same level
of representation (underlying values vs wrapper objects).
@Raibaz Raibaz merged commit 3b5e4df into mockk:master Oct 24, 2025
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.

2 participants