2016-09-07 87 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

感謝提供一個項目,該項目是很容易和簡單的解決這個問題。爲什麼我選擇另一個答案,因爲他告訴我爲什麼。這並不意味着你解決問題的更好方法是無用的,只是我更願意知道我錯在哪裏。所以,祝你有美好的一天。 –