mockk: Using mockkConstructor for File results in StackOverFlowError
Prerequisites
Please answer the following questions for yourself before submitting an issue.
- I am running the latest version
- I checked the documentation and found no answer
- I checked to make sure that this issue has not already been filed
Expected Behavior
Using mockkConstructor
for File
should work as expected.
Current Behavior
java.lang.StackOverflowError
occurrs
Failure Information (for bugs)
Please help provide information about the failure if this is a bug. If it is not a bug, please remove the rest of this template.
Steps to Reproduce
Please provide detailed steps for reproducing the issue.
- Try to mock
File
usingmockkConstructor
Context
Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.
- MockK version: 1.8.6
- OS: Mac OS X 10.13.6
- Kotlin version: 1.2.41
- JDK version: 1.8u161
- Type of test: unit test
Failure Logs
Please include any relevant log snippets or files here.
Stack trace
// -----------------------[ YOUR STACK STARTS HERE ] -----------------------
Exception in thread "main" java.lang.StackOverflowError
at io.mockk.impl.instantiation.JvmConstructorMockFactory$ConstructorInvocationHandler.invocation(JvmConstructorMockFactory.kt:81)
at io.mockk.proxy.jvm.advice.BaseAdvice.constructorDone(BaseAdvice.kt:33)
at java.io.File.<init>(File.java:374)
at sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:1279)
at sun.misc.URLClassPath.getResource(URLClassPath.java:239)
at java.net.URLClassLoader$1.run(URLClassLoader.java:365)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at io.mockk.impl.instantiation.JvmConstructorMockFactory$ConstructorInvocationHandler.invocation(JvmConstructorMockFactory.kt:81)
// -----------------------[ YOUR STACK TRACE ENDS HERE ] -----------------------
Minimal reproducible code (the gist of this issue)
// -----------------------[ YOUR CODE STARTS HERE ] -----------------------
package io.mockk.gh
import io.mockk.every
import io.mockk.mockkConstructor
import org.junit.Assert.assertTrue
import org.junit.Test
import java.io.File
class FileTest {
@Test
fun testConstructorMockkForFile() {
mockkConstructor(File::class) {
every {
anyConstructed<File>().exists()
} returns true
}
assertTrue(File("x").exists())
}
}
// -----------------------[ YOUR CODE ENDS HERE ] -----------------------
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 8
- Comments: 15
Commits related to this issue
- Code to solve #121. Not finished — committed to mockk/mockk by oleksiyp 6 years ago
I performed pretty decent coding effort to make it work.
First, my goal was to solve a problem in general by protecting mockk from recursive calls to Java Library. This didn’t help to solve File issues. It is too tightly coupled to a classloader. Not sure I need to merge this code at all. Will keep it in a branch.
Then I ended up with a solution that scans stack trace and detects the previous call of File method(actually any method alike) if it is a call from Java internals it allows to process it as a regular call. It works, but performance degradation is way too big. Alike 13 seconds for the code you’ve posted.
In general, this integration topic with JVM is a way too complex. I decided to deal with it on best effort basis. Not forbidding it, but not saying that all possible combinations are supported. So that’s it. My best efforts. By closing this issue I conclude that it is very hard to achieve this and is not supported for now.
Any chance this issue will be fixed in the future?
Any news or workaround available? I am also facing same issue-
mockkStatic(File::class) every { File(anyString()).exists() } returns true
Any news or workaround available yet? This is a bit of a blocker for us…
What is the workaround for this ?
Happens with URL class as well. Regarding files, I have had success testing files using an in-memory filesystem (as long as you’re using nio everywhere): com.github.marschall:memoryfilesystem - no need to mock in that case.
I found a workaround. In my case I needed to mock
writeBytes
beforehandInstead of using
mockkStatic
create a util class lets say(ABCUtil) . And Keep your functions in that util class. Then mock that class usingmockkObject(ABCUtil)
and test your functions. @oscar0812 @bosankus