mockito / mockito-kotlin

Using Mockito with Kotlin
MIT License
3.1k stars 200 forks source link

whenever() cannot handle Spring-Boot @SpyBean #391

Open avisecag opened 3 years ago

avisecag commented 3 years ago

I'm trying to migrate a spring-boot project from an older mockito-kotlin version to mockitokotlin2, and facing some difficulties. I'm not entirely sure if I might just be doing something very wrong, but I went as far as checking out mockitokotlin2 and look at the tests to make sure I got the syntax right.

The problem really only seems to be present when working with spring-boot, that is, specifically when using something like a @SpyBean annotation, which means the spy is instantiated by spring-boot and I cannot call mock() directly.

I did try to force spring-boot to use mockito 2, but it doesn't seem to help:

buildscript {
    dependencies {
        classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.6")
        classpath("org.jetbrains.kotlin:kotlin-allopen:1.4.0")
        // liquibase stuff
        classpath("mysql:mysql-connector-java:5.1.44")
        classpath("org.yaml:snakeyaml:1.19")
        classpath("org.liquibase:liquibase-gradle-plugin:1.2.3") {
            exclude("org.liquibase", "liquibase-core")
        }
        classpath("org.liquibase:liquibase-core:3.8.9") // should be in sync with the version included in spring boot
    }
    extra.set("mockito.version", "2.23.0")
}

Most things work without issue, but when I have to use whenever() (like for example for doNothing() or doAnswer()), mockito complains:

org.mockito.exceptions.misusing.NotAMockException: Argument passed to when() is not a mock! Example of correct stubbing: doThrow(new RuntimeException()).when(mock).someMethod(); at com.nhaarman.mockitokotlin2.StubberKt.whenever(Stubber.kt:65)

The syntax I'm using is pretty standard and matches how I saw doNothing() used in the mockitokotlin2 tests. This is what it looked befre the migration (using Mockito calls directly):

doNothing().`when`(imageTableService).moveToTrash(any(), any())

When working with mockitokotlin2, tests using this suddenly fail (doNothing seems to be ignored and the spied method is executed), so I tried to rewrite it using the mockitokotlin calls instead, hoping that would solve the problem (I also changed the imports, obviously):

doNothing().whenever(imageTableService).moveToTrash(any(), any())

However, now it just throws the error I posted above, apparently not liking the spy that was created by spring-boot. Is there any way around this, or do I just have to stick to older mockito versions while using @MockBean or @SpyBean?