模拟属性设置器

roz*_*ina 1 unit-testing mockito kotlin

我想在我的测试中模拟一个属性设置器,但我找不到任何关于它是如何做到的。这是我迄今为止尝试过的:

interface Foo
{
    var property: Int
}

@RunWith(MockitoJUnitRunner::class)
class TestClass
{
    @Mock private val fooMock: Foo = mock()
    private var temp = 0

    @Before
    fun setup()
    {
        whenever(fooMock.property).then {
            invocation ->
            if (invocation.arguments.isEmpty())
            {
                // this part works fine
                return@then 15
            }
            else
            {
                // this never gets called
                temp = invocation.getArgument(0)
                null
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:我正在使用 com.nhaarman.mockito_kotlin 库

zsm*_*b13 5

一个有点丑陋但有效的模拟 setter 的解决方案,使用绑定的属性引用来获取 setter:

whenever(fooMock::property.setter.invoke(any())).then {
    println("setter called with ${it.arguments[0]}")
}
Run Code Online (Sandbox Code Playgroud)

一些替代方案:

如果要验证属性是否设置为给定值,可以执行以下操作:

fooMock.property = 25

verify(fooMock).property = 25
Run Code Online (Sandbox Code Playgroud)

如果要捕获属性设置的值,可以使用ArgumentCaptor,如下所示:

class TestClass {
    @Mock private lateinit var fooMock: Foo
    @Captor private lateinit var captor: ArgumentCaptor<Int>

    @Test
    fun test() {
        fooMock.property = 25

        verify(fooMock).property = capture(captor)

        assertEquals(25, captor.value)
    }
}
Run Code Online (Sandbox Code Playgroud)

Mockito 的一般提示:这两行都创建了一个模拟,您不需要同时使用@Mock注释和mock()方法。

@Mock private lateinit var fooMock: Foo

private val fooMock: Foo = mock()
Run Code Online (Sandbox Code Playgroud)