You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin单元测试中用Mockito捕获验证Int类型参数?

How to Capture Kotlin Int Parameters with Mockito ArgumentCaptor

I get it, dealing with Kotlin primitive types and Mockito's ArgumentCaptor can be tricky because of Java interop differences. Let's fix your code step by step.

The Problem with Your Current Code

  • ArgumentCaptor<Int>() can't be instantiated directly because its constructor is private.
  • Using Integer::class.java creates a captor for Java's Integer wrapper type, but your function expects Kotlin's Int (which maps to Java's primitive int), causing a type mismatch that blocks compilation.

The Best Solution: Use Mockito-Kotlin's Extension Function

Mockito-Kotlin has a handy argumentCaptor() extension that handles Kotlin-Java type conversions automatically. This is the most idiomatic approach for Kotlin projects.

First, ensure you have the latest Mockito-Kotlin dependency in your project. Then update your test code:

import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.argumentCaptor // Add this import
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.assertEquals

open class ClassUnderTest {
    open fun print(a: Int) {
        println("ClassUnderTest: $a")
    }
}

class CaptorTest {
    @Test
    fun testCaptor() {
        val testObject = mock<ClassUnderTest>()
        testObject.print(12)
        testObject.print(34)

        // Use Mockito-Kotlin's extension to create a typed captor
        val captor = argumentCaptor<Int>()

        // Verify the method calls and capture arguments
        verify(testObject, times(2)).print(captor.capture())

        // Validate the captured values
        assertEquals(listOf(12, 34), captor.allValues)
        assertEquals(12, captor.firstValue)
        assertEquals(34, captor.secondValue)
    }
}

Alternative: Raw Mockito (Without Mockito-Kotlin Extensions)

If you prefer to stick with plain Mockito, you can create a captor for the primitive int type using Int::class.javaPrimitiveType:

import org.mockito.ArgumentCaptor

// ... rest of your class code remains the same

@Test
fun testCaptor() {
    val testObject = mock<ClassUnderTest>()
    testObject.print(12)
    testObject.print(34)

    // Create captor for Kotlin Int (maps to Java primitive int)
    val captor = ArgumentCaptor.forClass(Int::class.javaPrimitiveType)
    
    verify(testObject, times(2)).print(captor.capture())
    
    // Validate captured values
    assertEquals(12, captor.firstValue)
    assertEquals(34, captor.secondValue)
}

Key Takeaways

  • Mockito-Kotlin's extensions eliminate most Kotlin-Java interop friction, so argumentCaptor<Int>() is the recommended approach.
  • When working with primitive types, always match the captor's type to the parameter's actual type (Kotlin Int ↔ Java primitive int, not the Integer wrapper).

内容的提问来源于stack exchange,提问作者Big Pumpkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:26:10