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

quarkus-junit5-mockito fails to mock basic Kotlin classes #42843

Closed
c-classen opened this issue Aug 28, 2024 · 2 comments
Closed

quarkus-junit5-mockito fails to mock basic Kotlin classes #42843

c-classen opened this issue Aug 28, 2024 · 2 comments
Labels
area/kotlin area/testing kind/question Further information is requested

Comments

@c-classen
Copy link
Contributor

Describe the bug

When including the quarkus-junit5-mockito dependency, Mockito fails to mock final classes, which is a problem especially for Kotlin, since all classes there are final if not explicitly declared open. This behavior is different from the one you get when you just include mockito-core in version 5.12.0, which is the same version Quarkus seems to use internally.

Even if you declare the class as open, the mock will behave differently to plain Mockito. For example, with plain Mockito, if you set a property of the mocked class, this will show as a setter invocation when using the Mockito.mockingDetails method. However, when using the Quarkus dependency, no such invocation is shown.

Expected behavior

Given the following Kotlin class:

class TestClass {
    lateinit var someProperty: String
}

and the following test method:

@Test
fun mockTestClass() {
    val mock = Mockito.mock(TestClass::class.java)
    mock.someProperty = "Hello"
    assertEquals(1, Mockito.mockingDetails(mock).invocations.size)
}

I would expect the test to complete successfully.

Actual behavior

The Mockito.mock call fails:

Cannot mock/spy class org.acme.TestClass
Mockito cannot mock/spy because :
 - final class

Even after adding an open in front of the TestClass, it still fails to show the setting of the property as a method invocation and the assertion fails.

How to Reproduce?

reproducer.zip

You can switch the dependencies in the pom.xml and add the open keyword in front of the TestClass and execute the tests to see the different behaviors.

Output of uname -a or ver

Linux some-Laptop 6.5.0-45-generic #45~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Jul 15 16:40:02 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "21.0.2" 2024-01-16 LTS

Quarkus version or git rev

3.14

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.8

Additional information

No response

@c-classen c-classen added the kind/bug Something isn't working label Aug 28, 2024
Copy link

quarkus-bot bot commented Aug 28, 2024

/cc @geoand (kotlin,testing)

@c-classen
Copy link
Contributor Author

I figured it out and it is actually intended behavior. Here is my solution for anyone that might stumble on the problem with Kotlin that I described:

Quarkus uses the "subclass" variant of Mockito by default instead of the "inline" variant, which is Mockito's default. To get Mockito's default behavior, just follow this guide if you use Maven or add the following in your build.gradle.kts if you use Gradle:

implementation("io.quarkus:quarkus-junit5-mockito") {
    exclude("org.mockito", "mockito-subclass")
}
implementation("org.mockito:mockito-core:5.8.0")

@geoand geoand added kind/question Further information is requested and removed kind/bug Something isn't working labels Aug 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/kotlin area/testing kind/question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants