一个简单的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) ... 

我怀疑为什么该方法不是一个模拟方法调用…

所以请帮助我,谢谢。

2 Solutions collect form web for “一个简单的kotlin类与mockito测试引起MissingMethodInvocationException”

默认情况下,Kotlin的课程和成员是最终的 。 Mockito不能嘲笑最终课程或方法 。 要使用Mockito,你需要open你想要模拟的方法:

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

进一步阅读

  • 在Kotlin中可以使用Mockito吗?
  • 没有开放课程,可以和Kotlin一起使用Mockito吗?

PS。 在我看来,只要你通过ISP保持你的接口小,使用Mockito或其他模拟框架的测试代码很少比手写的假货/存根更易读易懂。

正如@miensol所提到的,你的问题发生是因为类在Kotlin中默认是final的。 错误信息不是很清楚,虽然这部分提到final的可能原因之一:

  1. 你存根: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类

这将自动覆盖您的用例,允许所有类别被嘲笑,否则将不被允许。

  • 测试两个目录树的相等性
  • 在kotlinunit testing中获得lambda捕获器的调用计数
  • doReturn不作为代理,但调用我的方法
  • Android Studio + Spek集成
  • kotlin mockk没有回答发现错误
  • Mockito可以在方法调用时根据它们的值validation参数吗?
  • 为什么$ MockitoMock $实例不被识别为模拟?
  • Androidunit testing没有被嘲笑
  • 我应该如何测试Kotlin扩展function?
  • Kotlin - Maven不执行测试
  • 不能在Kotlinunit testing(ExecutionException,Aapt2Exception)
  • Kotlin language will be the best programming language for Android.