【问题标题】:Mockito Kotlin rejects to work with extensionsMockito Kotlin 拒绝使用扩展
【发布时间】:2021-01-25 10:48:14
【问题描述】:

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

@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

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

【问题讨论】:

    标签: android kotlin mockito


    【解决方案1】:

    问题是ArgumentMatchers.any() 返回null,这与 Kotlin 不可为空的类型不能很好地配合。如果它在您的第一个 sn-p 中有效,那么我猜 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")
    }
    

    【讨论】:

    • 我不能,因为实际方法 feedbackManager.sendFeedbackToEmail(any()) 不适用于可空类型。我正在使用 com.nhaarman.mockito_kotlin - 它适用于 kotlin+nullable 等。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 2020-09-10
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      相关资源
      最近更新 更多