I have spring boot application with kotlin, and the thing is: I can't mock 3rd party final class only when @Retryable is used. Here is my project:
@Component
class RestClient {
fun getAllData() : List<String> = listOf("1")
}
@Service
class MyService(val restClient: RestClient) {
@Retryable(maxAttempts = 3)
fun makeRestCall() : List<String> {
return restClient.getAllData()
}
}
So I would like to test two cases:
- when
RestClient
throws HttpClientErrorException.NotFound exception,makeRestCall()
should returnnull
(that is not supported by current implementation by that does not matter) - when
makeRestCall()
is invoked - I would like to check with mockito that it is really invoked (no sense, but why can't I do it? )
Here is my test:
@EnableRetry
@RunWith(SpringRunner::class)
class TTest {
@MockBean
lateinit var restClient: RestClient
@SpyBean
lateinit var myService: MyService
@Test
fun `should throw exception`() {
val notFoundException = mock<HttpClientErrorException.NotFound>()
whenever(restClient.getAllData()).thenThrow(notFoundException)
}
@Test
fun `method should be invoked`() {
myService.makeRestCall()
verify(myService).makeRestCall()
}
}
In order to mock final class org.springframework.web.client.HttpClientErrorException.NotFound
, I've added mockito-inline as dependency
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
So, here is the problem:
when I run my tests with mockito-inline as dependency:
- test
should throw exception
- passes - test
method should be invoked
- fails with exception :Argument passed to verify() is of type MyService$$EnhancerBySpringCGLIB$$222fb0be and is not a mock!
when I run my tests without mockito-inline as dependency:
- test
should throw exception
- fails with exception:Mockito cannot mock/spy because : final class
- test `method should be invoked - passes
when I run my tests without @EnableRetry - both tests passes, but I'm not able to test retry functionality
How can I deal with that?