Search code examples
spring-bootspring-retryspringmockito

SpringBoot testing with spring-retry


I had the following function (the function is not really important):

    fun myRandomFunc(something: String?): List<Int> {
        return listOf(5)
    }

And you can imagine it was doing some API calls, returning list of some objects, etc. I could easily mock this function in test like this:

        doReturn(
            listOf(
                5
            )
        )
            .whenever(...).myRandomFunc("something")

But after I introduced (retry/recover) in the mix, that mock is now throwing org.mockito.exceptions.misusing.NotAMockException at .... Any idea why?

This is the code with spring retry:

    @Retryable(
        value = [ApiException::class], maxAttempts = MAX_RETRIES,
        backoff = Backoff(delay = RETRY_DELAY, multiplier = RETRY_MULTIPLIER, random = true)
    )
    fun myRandomFunc(something: String?): List<Int> {
        return listOf(5)
    }

    @Recover
    fun testMyRandomFunc(exception: Exception): List<Int> {
        log.error("Exception occurred ...", exception)
        throw RemoteServiceNotAvailableException("Call failed after $MAX_RETRIES retries")
    }

The code works, it's functional, just the mocking of tests is now broken. Would appreciate some help


Solution

  • Spring retry creates a proxy around the object.

    If there is an interface, the proxy is a JDK proxy; if not, CGLIB is used.

    Mockito can't mock CGLIB (final) methods.