mockk
mockk copied to clipboard
Cannot use `mockkObject` in a interface's lambda implementation
Just be aware about usual MockK support pattern. Tickets are checked from time to time, replied, discussed, labeled, e.t.c. But real fixes are applied in a month-two month period in a bunch. If you think this is unacceptable, go on, join the project, change the world.
Please remove sections wisely
Below information is actually needed to make all the process of fixing faster. Choose main points. Don't blindly follow this as a set of rules. Don't waste much time. Usually, the main thing is to have a good reproducible minimal code.
Prerequisites
Please answer the following questions for yourself before submitting an issue.
- [x] I am running the latest version
- [x] I checked the documentation and found no answer
- [x] I checked to make sure that this issue has not already been filed
Expected Behavior
The interface implementation inside an inner class should be mocked when using mockkObject
Current Behavior
When switching from Kotlin language version 1.4 to 1.5 a warning start to happen when running the test WARNING: Non instrumentable classes(skipped): class CustomInterfaceTests$Config$$Lambda$311/0x00000008001da440
. With this warning, the object cannot be mocked, therefore failing inside the every { ... }
Failure Information (for bugs)
Jan 13, 2022 10:49:00 AM io.mockk.impl.log.JULLogger warn
WARNING: Non instrumentable classes(skipped): class CustomInterfaceTests$Config$$Lambda$311/0x00000008001da440
Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
io.mockk.MockKException: Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
Steps to Reproduce
Please provide detailed steps for reproducing the issue.
- Create a Java interface, i.e
CustomInterface
with a single methodvoid doStuff()
- Create a test, mock the interface inside the test
class CustomInterfaceTests {
val CUSTOM_INTERFACE: CustomInterface = CustomInterface { }
@Test
fun `test`() {
mockkObject(CUSTOM_INTERFACE)
every { CUSTOM_INTERFACE.doStuff() } returns Unit
}
}
- Run the test and see that it fails with the stacktrace provided
- Instead of
val CUSTOM_INTERFACE: CustomInterface = CustomInterface { }
, useval CUSTOM_INTERFACE: CustomInterface = CustomInterfaceImpl()
, the test passes. - If lowering the language version < 1.5, the test passes
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.12.2
- OS: macOS Big Sur 11.6.1
- Kotlin version: 1.6.10
- JDK version: 11
- JUnit version: 5
- Type of test: unit test
Failure Logs
Please include any relevant log snippets or files here.
Stack trace
Jan 13, 2022 10:59:22 AM io.mockk.impl.log.JULLogger warn
WARNING: Non instrumentable classes(skipped): class CustomInterfaceTests$$Lambda$288/0x00000008001d4440
Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
io.mockk.MockKException: Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:64)
at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30)
at io.mockk.MockKDsl.internalEvery(API.kt:93)
at io.mockk.MockKKt.every(MockK.kt:98)
Minimal reproducible code (the gist of this issue)
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.6.10"
application
}
group = "me.mhertdacoreg"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation(kotlin("test"))
implementation("io.mockk:mockk:1.12.2")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
languageVersion = "1.5"
apiVersion = "1.5"
jvmTarget = "11"
}
}
application {
mainClass.set("MainKt")
}
public interface CustomInterface {
void doStuff();
}
import io.mockk.every
import io.mockk.mockkObject
import org.junit.jupiter.api.Test
class CustomInterfaceTests {
val CUSTOM_INTERFACE: CustomInterface = CustomInterface { }
// val CUSTOM_INTERFACE: CustomInterface = CustomInterfaceImpl()
@Test
fun `test`() {
mockkObject(CUSTOM_INTERFACE)
every { CUSTOM_INTERFACE.doStuff() } returns Unit
}
}
Am I missing some change between 1.4 and 1.5?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale
just ask to put an important
label.
The fact that you mention that lowering the language version to below 1.5 makes me think this is due to the change introduced in 1.5.0 about SAM interfaces: https://kotlinlang.org/docs/whatsnew15.html#sam-adapters-via-invokedynamic
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale
just ask to put an important
label.