本文介绍了一个带有Mockito测试的简单kotlin类导致MissingMethodInvocationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始学习Kotlin和Mockito,因此我编写了一个简单的模块对其进行测试.

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

AccountData_K.kt:

AccountData_K.kt:

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

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

AccountDataMockTest_K.kt:

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)
    }
}

当我运行测试时,它报告有关testChangeLogin()方法的异常:

And when I run the test, it reports an exception 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...

所以请帮助我,谢谢.

推荐答案

默认情况下,Kotlin的类和成员是最终的. Mockito无法模拟最终类或方法.要使用Mockito,您需要open您想要模拟的方法:

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
}

进一步阅读

  • Is it possible to use Mockito in Kotlin?
  • Is it possible to use Mockito with Kotlin without open the class?

PS.以我的拙见,只要您通过 ISP (一种测试代码,使用Mockito或其他模拟框架比手写的假货/存根几乎没有可读性和易懂性.

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.

这篇关于一个带有Mockito测试的简单kotlin类导致MissingMethodInvocationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 05:33