I am not really certain how to use Mockito in Kotlin properly. I want a simple way, which not only works (both solutions below work), but also has a working unused mock detection (I know that this simple test does not make any sense)
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
@ExtendWith(MockitoExtension::class)
class MockitoTest {
// private val toTest by lazy { mock<Foo>() } // unused mock usage detected
private val toTest = mock<Foo>() // unused mock usage NOT detected
@Test
fun `unused mock usage is detected`() {
whenever(toTest.bla()).thenReturn("unused")
}
}
interface Foo {
fun bla(): String
}
Anyone has an idea how to avoid the “by lazy” → I am searching ideally for a solution which can be asserted using ArchUnit.
Thank you for your answer!
Best not to use Mockito, but MockK (https://mockk.io/) instead, which already comes with a lot of benefits. If you are using spring the ninjasquad plugin would be recommended (Imho).
MockK works the same kind of magic Mockito does, but integrates better with the language. Take this (non-compiling) snippet for instance:
@MockK
lateinit var myMock: MyClass
@InjectMocks
lateinit var classUnderTest: SomeClass // takes one param (MyClass)
@Test
fun someTest() {
// define how calls to myMock.doSomething are handled.
every { myMock.doSomething(someParam) } returns 42
// some call that internally calls myMock.doSomething()
classUnderTest.someCall()
// verify that myMock.doSomething() was actually called exactly once.
verify(exactly = 1) { myMock.doSomething(someParam) }
}
Thank you for your answer 
I guess switching the mocking framework is not desired, however using the annotations and therefore having an empty constructor (except for super call) would solve this problem.
It would be great to be possible to get rid of the lateinit
for those classes, but I guess that is not possible.
NOTE: MockK is recommended in the following Spring tutorial: Tutorial | Building web applications with Spring Boot and Kotlin.
It is still possible to use the basic syntax and inject the mocks yourself, and therefore getting rid of the annotation and the lateinit. Also, the instance constructor does not need to be empty. It can require values and still be safe to use. This is because Mockk uses proxies, so there is no actual instance of the original class (I believe Mockito works the same, but I am not sure as I have only migrated it, but never really used it). Take this example:
class SomeClass(val someVal: String) {
fun whoAmI(): String = "I am $someVal"
}
val someMock = mockk<SomeClass>()
val functionUnderTest: () -> String = { someMock.whoAmI() }
@Test
fun test_someClass() {
every { someMock.whoAmI() } returns "I am the MOCK!"
val result = functionUnderTest()
verify(exactly = 1) { someMock.whoAmI() }
assertEquals(result, "I am the MOCK!")
}
In the above example the Mock is directly created without lateinit
and without the annotation.
@TreffnonX That looks like my original solution - which works.
However from a maintainability perspective I really would like to have working unused mock detection…
The follwong test should fail as I am never calling bar 
It seems to me that mockk is missing the feature entirely. (Think from a maintainability perspective → having less obvious unused mocks is not a good idea)
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Test
class MyTest {
val mockedFoo = mockk<Foo>()
@Test
fun `unused mock detected`() {
every { mockedFoo.bar() } returns "MOCK"
}
}
interface Foo {
fun bar(): String;
}
It seems to me that the unused mock detection is not implemented in mockk at all Feature: verify strict mocking in Mockito sense · Issue #334 · mockk/mockk · GitHub, so mockk is not an alternative in this scenario yet.
Using @ExtendWith(MockitoExtension::class)
only considers mocks that are created after class instantiation (therefore using “by lazy” works fine). NOTE: That is what it feels to me, not how it officially is for me.
So Mocking itself seems to work, working with the Annotations enables this feature and using the lazy delegate makes it work (so would adding it to a @BeforeEach.
Thanks for your input!
I am unsure whether unused Mocks exists, I have to admit. But I have rarely heard of this as hard requirement. What is more interesting, though, but does exist is the confirmVerified
function, which ensures, that all calls that have been made to any mock have actually been verified. Since different test cases within a class will use different mocks, I can barely imagine that all mocks will always be used in every case, unless you only have one test function. But you have to know about your requirements yourself, so I guess there is a reason for that 
@reisi007 strict mocking is a very interesting topic. Do you have any good examples where it ‘saves lives’? I do understand the implications of unnecessary mockings, but when you try to optimise tests, you would want to set up mocks for all methods of an instance once and then re-use it everywhere, which would then contradict strict mocking. Both options are valid for me.
Thanks.
@achmyr : Imagine the following service:
class TestService(private val securityService: SecurityService) {
fun call(user:User,payload:Payload) {
if(securityService.isAllowed(user) && payload.isValid() ){
doStuff(payload)
}
}
In the scenario above I deem it to be useful to know if securityService is actually invoked. If the AND is switched, the SecurityService is not called on an invalid payload.
If there was no unused mock detection the (possible important) call can be skipped. (Note: It basically is a verify called at least once, which is auto applied)
If you put your “whenever” call in a private method, a per test setup does not seem to be that bad
.
Did I manage to answer your question?
1 Like