一个简单的kotlin类与mockito测试引起MissingMethodInvocationException
我开始学习Kotlin和Mockito,所以我编写了一个简单的模块来测试它。
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) } }
当我运行测试时,它会报告有关testChangeLogin()
方法的exception:
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) ...
我怀疑为什么该方法不是一个模拟方法调用…
所以请帮助我,谢谢。
默认情况下,Kotlin的课程和成员是最终的 。 Mockito不能嘲笑最终课程或方法 。 要使用Mockito,你需要open
你想要模拟的方法:
open fun changeLogin() : Boolean { return !isLogin }
进一步阅读
- 在Kotlin中可以使用Mockito吗?
- 没有开放课程,可以和Kotlin一起使用Mockito吗?
PS。 在我看来,只要你通过ISP保持你的接口小,使用Mockito或其他模拟框架的测试代码很少比手写的假货/存根更易读易懂。
正如@miensol所提到的,你的问题发生是因为类在Kotlin中默认是final
的。 错误信息不是很清楚,虽然这部分提到final
的可能原因之一:
- 你存根:final / private / equals()/ hashCode()方法。
有一个项目专门用来帮助处理Kotlin在Mockito的unit testing中“默认最终”。 对于JUNIT,您可以使用kotlin-testrunner ,这是一种简单的方法,可以让任何Kotlin测试自动打开类,以便在类加载器加载时进行测试。 用法很简单,只需添加@RunWith(KotlinTestRunner::class)
一个注释,例如:
@RunWith(KotlinTestRunner::class) class MyKotlinTestclass { @Test fun test() { ... } }
这篇文章在文章Never say final里被彻底的讲述了:在unit testing中嘲笑Kotlin类
这将自动覆盖您的用例,允许所有类别被嘲笑,否则将不被允许。