David_Jiang David_Jiang - 2 months ago 14
Android Question

A simple kotlin class with mockito test caused MissingMethodInvocationException

I start to learn Kotlin and Mockito, so I code a simple module to test it.

AccountData_K.kt:

open class AccountData_K {
var isLogin: Boolean = false
var userName: String? = null

fun changeLogin() : Boolean {
return !isLogin
}
}


AccountDataMockTest_K.kt:

class AccountDataMockTest_K {
@Mock
val accountData = AccountData_K()

@Before
fun setupAccountData() {
MockitoAnnotations.initMocks(this)
}

@Test
fun testNotNull() {
assertNotNull(accountData)
}

@Test
fun testIsLogin() {
val result = accountData.changeLogin()
assertEquals(result, true)
}

@Test
fun testChangeLogin() {
`when`(accountData.changeLogin()).thenReturn(false)
val result = accountData.changeLogin()
assertEquals(result, false)
}
}


And when I run the Test, it report an Error about the testChangeLogin() method:

org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.

at com.seal.materialdesignwithkotlin.AccountDataMockTest_K.testChangeLogin(AccountDataMockTest_K.kt:57)
...


I doubt why the method is not a method call on a mock...

So please help me, thanks at all.

Answer

By default Kotlin's classes and members are final. Mockito is not able to mock final classes nor methods. To use Mockito you need to open the method you wish to mock:

open fun changeLogin() : Boolean {
    return !isLogin
}

Further reading

PS. In my humble opinion, as long as you keep you interfaces small through i.e ISP, a test code that uses Mockito or other mocking framework is rarely more readable and easy to understand than hand written fakes/stubs.

Comments