Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use mockkObject in a interface's lambda implementation #781

Open
3 tasks done
marcusdacoregio opened this issue Jan 13, 2022 · 3 comments
Open
3 tasks done
Labels

Comments

@marcusdacoregio
Copy link

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.

  • 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

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.

  1. Create a Java interface, i.e CustomInterface with a single method void doStuff()
  2. 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
    }

}
  1. Run the test and see that it fails with the stacktrace provided
  2. Instead of val CUSTOM_INTERFACE: CustomInterface = CustomInterface { }, use val CUSTOM_INTERFACE: CustomInterface = CustomInterfaceImpl(), the test passes.
  3. 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?

@stale
Copy link

stale bot commented Apr 16, 2022

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.

@stale stale bot added the stale label Apr 16, 2022
@Raibaz
Copy link
Collaborator

Raibaz commented Apr 16, 2022

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

@stale stale bot removed the stale label Apr 16, 2022
@stale
Copy link

stale bot commented Jul 10, 2022

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.

@stale stale bot added the stale label Jul 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants