Fix StackOverflowError when mocking methods returning ArrayList #1464
+214
−6
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes StackOverflowError when using
every/verifywith methods returningArrayListor other concrete collection types on Android.Root Cause
The
MethodDescriptorconstructor was using Kotlin collection operations (dropLastWhile,filter) that internally callisEmpty()on collections. When the collection class (likeArrayList) is being mocked, this triggers the mock dispatcher, which callsAdvice.getOrigin(), which creates a newMethodDescriptor, causing infinite recursion.Solution
Rewrote
MethodDescriptor.parseParamTypes()to use a two-pass approach that avoids collection operations entirely:This approach avoids:
dropLastWhile { it.isEmpty() }- callsisEmpty()on collectionsfilter { it != "" }- also calls collection methodsString.trim()- replaced with customtrimSubstring()to avoid any potential collection operationsHelper functions
hasNonWhitespaceContent()andtrimSubstring()ensure consistent logic between both passes and avoid triggering mocked methods.Testing
ArrayListReturnTypeTest.ktfor Android instrumented testingFixes #1450
Original prompt
This section details on the original issue you should resolve
<issue_title>java.lang.StackOverflowError when use every/verify{/a method return ArrayList/} on a mock class after 1.13.8</issue_title>
<issue_description>I update the mockk from 1.12 to 1.13.x/1.14.x to support Android 14, but it will throw StackOverflowError when run some cases, after my testing, find the way to reproduce it.
Test code:
It always throw this StackOverflowError
Workaround:
Test code:
But actually, we need mock the class from SDK, we cannot change the return type.
Would anyone have any idea to fix it?</issue_description>
Comments on the Issue (you are @copilot in this section)
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.