【问题标题】:How to use mockito to test that callback is invoked with Kotlin如何使用 mockito 测试使用 Kotlin 调用的回调
【发布时间】:2020-09-19 11:52:07
【问题描述】:

我有一个接受回调的 Kotlin 类,如下:

class MyKotlinClass (private val handleSomeCallBack: (ByteArray) -> Unit) {
    private val someBuffer = BytesBuilder()

    fun myFunction(bytesList: List<Byte>) {
        handleSomeCallBack(someBuffer.toArray())
    }
}

我不太清楚如何使用 Mockito 和 jUnit 来测试回调是否被调用。

我觉得我应该使用argumentCaptor 而不是间谍,但不太确定。

我目前的情况如下:

@RunWith(MockitoJUnitRunner::class)
class MyKotlinClassTests : BaseTest() {
    private lateinit var myKotlinClass: MyKotlinClass

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
    }

    @Test
    fun `test callback is called when message is passed in`() {
        val captor = argumentCaptor<(data: ByteArray) -> Unit>()

        myKotlinClass = MyKotlinClass(capture(captor))

        val rawDataBytes = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05)

        myKotlinClass.myFunction(rawDataBytes.toList())

        verify(captor, once())
    }
}

使用上述方法,我收到以下错误:

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method MyKotlinClass.<init>, parameter handleSomeCallBack

测试我的回调是否被调用并评估与它一起传递的数据的正确方法是什么 (someBuffer)?

【问题讨论】:

  • 尝试验证回调,而不是你的回调捕获者stackoverflow.com/questions/53306884/…
  • 第一个问题是:private var myCallbackCaptor: ArgumentCaptor? = null 导致错误,即 Unresolved Reference myCallBack
  • 我不使用 mockito,但问题可能是使用 lateinit 进行初始化或在 setUp 中进行初始化...另一个选项可能是更改方法,通过构造函数删除 lambda 并使用暂停返回 byteArray 值的函数
  • 所以,我已经更改了代码来解决最初的错误,但现在我得到了一个稍微不同的错误......我已经编辑了描述。

标签: unit-testing kotlin callback mockito


【解决方案1】:

解决方法如下:

@RunWith(MockitoJUnitRunner::class)
class MyKotlinClassTests : BaseTest() {

    @Mock
    private lateinit var handleSomeCallBack: (ByteArray?) -> Unit

    private lateinit var myKotlinClass: MyKotlinClass

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
    }

    @Test
    fun `test callback is called when message is passed in`() {
        myKotlinClass = MyKotlinClass(handleSomeCallBack)

        val inputBytes = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05)
        val expectedBytes = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05)

        myKotlinClass.myFunction(inputBytes.toList())

        verify(handleSomeCallBack, once()).invoke(expectedBytes)
    }
}

由于回调是在我的课堂上而不是模拟中,所以使用捕获器是错误的解决方案。

【讨论】:

    【解决方案2】:

    你不需要 mockito。 只需创建 lamda 并将您的值存储在列表中,然后断言这些值。

        @Test
        fun `test callback is called when message is passed in`() {
         val captor = arrayListOf<ByteArray>()
    
         val myKotlinClass = MyKotlinClass ({
            captor.add(it)
         })
    
         val rawDataBytes = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05)
    
         myKotlinClass.myFunction(rawDataBytes.toList())
    
        //Assert size
        Assert.assertTrue(captor.size == 1)
    
        //Assert ByteArray values
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      相关资源
      最近更新 更多