Mockito Kotlin 拒绝使用扩展
Mockito Kotlin rejects to work with extensions
在我的单元测试中,我有一个非常简单的案例 - 使用方法调用模拟来模拟 class。像这样:
@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()
returns null
,它不能很好地处理 Kotlin 不可空类型。如果它在您的第一个代码段中有效,那么我猜 sendFeedbackToEmail
参数必须可以为空(或者它是 Java class)。但是 mockSendFeedbackToEmail
中的 feedbackText
不可为空,因此 Kotlin 编译器会在那里插入空检查。因此 NullPointerException.
尝试将方法签名更改为:
fun FeedbackManager.mockSendFeedbackToEmail(feedbackText: String? = any()) {
...
}
如果 sendFeedbackToEmail
参数不可为 null 而您使用的是 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())
}
在我的单元测试中,我有一个非常简单的案例 - 使用方法调用模拟来模拟 class。像这样:
@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()
returns null
,它不能很好地处理 Kotlin 不可空类型。如果它在您的第一个代码段中有效,那么我猜 sendFeedbackToEmail
参数必须可以为空(或者它是 Java class)。但是 mockSendFeedbackToEmail
中的 feedbackText
不可为空,因此 Kotlin 编译器会在那里插入空检查。因此 NullPointerException.
尝试将方法签名更改为:
fun FeedbackManager.mockSendFeedbackToEmail(feedbackText: String? = any()) {
...
}
如果 sendFeedbackToEmail
参数不可为 null 而您使用的是 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())
}