Mockito Kotlin拒绝使用扩展



在我的单元测试中,我有一个非常简单的用例模拟类,它带有一个方法调用模拟。像这样:

@Mock
private lateinit var feedbackManager: FeedbackManager
...
Mockito.`when`(feedbackManager.sendFeedbackToEmail(any())).thenReturn(Completable.complete())

所以这工作得很好,我可以模拟和验证方法调用。没问题。

我决定稍微改进一下,并在我的FeedbackManager中添加了一个扩展,看起来像这样:

fun FeedbackManager.mockSendFeedbackToEmail(feedbackText: String = any()) {
Mockito.`when`(this.sendFeedbackToEmail(feedbackText)).thenReturn(Completable.complete())
}

你可以看到一切都是一样的在这个扩展,因为它是之前添加它。但由于某些原因,这种方法不起作用:

java.lang.NullPointerException: Parameter specified as non-null is null: method
package.FeedbackManagerMockingKt.mockSendFeedbackToEmail, parameter feedbackText

你能在这里给出建议吗?有可能实现我想要的吗?

问题是ArgumentMatchers.any()返回null,这与Kotlin非空类型不能很好地发挥作用。如果它在第一个代码片段中工作,那么我猜sendFeedbackToEmail参数必须是可空的(或者它是一个Java类)。但是mockSendFeedbackToEmail中的feedbackText是不可空的,所以Kotlin编译器在那里插入了空检查。因此NullPointerException。

尝试将方法签名更改为:

fun FeedbackManager.mockSendFeedbackToEmail(feedbackText: String? = any()) {
...
}

如果sendFeedbackToEmail参数不可为空,并且您正在使用com.nhaarman.mockito_kotlin,您可以尝试以下操作:

fun FeedbackManager.mockSendFeedbackToEmail(feedbackText: String? = null) {
Mockito.`when`(this.sendFeedbackToEmail(feedbackText ?: any())).thenReturn("OK")
}

或者只是重载函数而不是使用默认值(以避免像:feedbackManager.mockSendFeedbackToEmail(null)这样的有点误导的调用):

fun FeedbackManager.mockSendFeedbackToEmail() {
Mockito.`when`(this.sendFeedbackToEmail(any())).thenReturn("OK")
}
fun FeedbackManager.mockSendFeedbackToEmail(feedbackText: String) {
Mockito.`when`(this.sendFeedbackToEmail(feedbackText)).thenReturn("OK")
}

问题是any()在任何情况下都不能正常工作:作为参数,在函数内,作为参数。所以我的解决方案是内联这个函数(添加一个inline修饰符)。

inline fun FeedbackManager.mockSendFeedbackToEmail(feedbackText: String = any()) {
Mockito.`when`(this.sendFeedbackToEmail(feedbackText))
.thenReturn(Completable.complete())
}

最新更新