2016-09-07 89 views
2

我开始学习Kotlin和Mockito,所以我编写了一个简单的模块来测试它。一个简单的kotlin类与mockito测试引起MissingMethodInvocationException

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()方法异常:

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

我怀疑为什么该方法不是模拟方法调用...

所以请帮助我,谢谢。

+0

可能的重复[是否有可能在没有打开类的情况下使用Mockito和Kotlin?](http://stackoverflow.com/questions/36536727/is-it-possible-to-use-mockito-with-kotlin-没有开放课堂) –

回答

2

默认Kotlin的classes and members are final。 Mockito不能够mock final classes nor methods。要使用你的Mockito需要open你想的方法来模拟:

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

进一步阅读

PS。在我看来,只要你通过ISP保持你的接口很小,使用Mockito或其他嘲讽框架的测试代码很难比手写的假货/存根更易于理解。

+0

谢谢,并且对于我引起简单问题的Kotlin肤浅知识感到抱歉。您的进一步阅读链接是非常有用的。祝你有美好的一天。 –

4

由于@miensol提到,您的问题发生的原因是默认情况下Kotlin中的类为final。 ()最终/私营/等于/ hashCode()方法:

  1. 你存根任:虽然这部分提到final为的可能原因之一错误消息还不是很清楚。

有一个项目专门协助处理科特林“最终默认”与单位的Mockito测试。对于JUNIT,您可以使用kotlin-testrunner这是一种简单的方法,使Kotlin测试可以在类加载器加载时自动打开测试类。使用方法很简单,只需添加一个注释的@RunWith(KotlinTestRunner::class),例如:

@RunWith(KotlinTestRunner::class) 
class MyKotlinTestclass { 
    @Test 
    fun test() { 
    ... 
    } 
} 

这是完全覆盖的文章Never say final: mocking Kotlin classes in unit tests

这允许所有类是涉及您的使用情况自动方式嘲笑否则不会被允许。

+0

感谢提供一个项目,该项目是很容易和简单的解决这个问题。为什么我选择另一个答案,因为他告诉我为什么。这并不意味着你解决问题的更好方法是无用的,只是我更愿意知道我错在哪里。所以,祝你有美好的一天。 –