Skip to content

Commit cd16b04

Browse files
authored
Merge pull request #91 from nhaarman/improve-captors
Improve argument captors
2 parents fd98501 + 80dbefd commit cd16b04

File tree

4 files changed

+52
-10
lines changed

4 files changed

+52
-10
lines changed

mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,32 @@
2626
package com.nhaarman.mockito_kotlin
2727

2828
import org.mockito.ArgumentCaptor
29+
import kotlin.reflect.KClass
30+
31+
inline fun <reified T : Any> argumentCaptor(): KArgumentCaptor<T> = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
2932

30-
inline fun <reified T : Any> argumentCaptor() = ArgumentCaptor.forClass(T::class.java)
3133
inline fun <reified T : Any> capture(captor: ArgumentCaptor<T>): T = captor.capture() ?: createInstance<T>()
34+
35+
@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()"))
36+
inline fun <reified T : Any> capture(captor: KArgumentCaptor<T>): T = captor.capture()
37+
38+
class KArgumentCaptor<out T : Any>(private val captor: ArgumentCaptor<T>, private val tClass: KClass<T>) {
39+
40+
val value: T
41+
get() = captor.value
42+
43+
val allValues: List<T>
44+
get() = captor.allValues
45+
46+
fun capture(): T = captor.capture() ?: createInstance(tClass)
47+
}
48+
49+
/**
50+
* This method is deprecated because its behavior differs from the Java behavior.
51+
* Instead, use [argumentCaptor] in the traditional way, or use one of
52+
* [argThat], [argForWhich] or [check].
53+
*/
54+
@Deprecated("Use argumentCaptor() or argThat() instead.")
3255
inline fun <reified T : Any> capture(noinline consumer: (T) -> Unit): T {
3356
var times = 0
3457
return argThat { if (++times == 1) consumer.invoke(this); true }

mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ inline fun <reified T : Any?> anyArray(): Array<T> = Mockito.any(Array<T>::class
5353

5454
inline fun <reified T : Any> argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat<T> { it -> (it as T).predicate() } ?: createInstance(T::class)
5555
inline fun <reified T : Any> argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate)
56+
inline fun <reified T : Any> check(noinline predicate: (T) -> Unit) = Mockito.argThat<T> { it -> predicate(it); true } ?: createInstance(T::class)
5657

5758
fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!!
5859
fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!!
Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
1+
import com.nhaarman.expect.expect
12
import com.nhaarman.mockito_kotlin.argumentCaptor
23
import com.nhaarman.mockito_kotlin.mock
4+
import com.nhaarman.mockito_kotlin.times
35
import com.nhaarman.mockito_kotlin.verify
4-
import com.nhaarman.expect.expect
5-
import com.nhaarman.mockito_kotlin.capture
66
import org.junit.Test
77
import java.util.*
88

99
class ArgumentCaptorTest {
1010

1111
@Test
1212
fun explicitCaptor() {
13+
/* Given */
1314
val date: Date = mock()
14-
val time = argumentCaptor<Long>()
1515

16+
/* When */
1617
date.time = 5L
1718

18-
verify(date).time = capture(time)
19-
expect(time.value).toBe(5L)
19+
/* Then */
20+
val captor = argumentCaptor<Long>()
21+
verify(date).time = captor.capture()
22+
expect(captor.value).toBe(5L)
2023
}
2124

2225
@Test
23-
fun implicitCaptor() {
26+
fun argumentCaptor_multipleValues() {
27+
/* Given */
2428
val date: Date = mock()
29+
30+
/* When */
2531
date.time = 5L
32+
date.time = 7L
2633

27-
verify(date).time = capture {
28-
expect(it).toBe(5L)
29-
}
34+
/* Then */
35+
val captor = argumentCaptor<Long>()
36+
verify(date, times(2)).time = captor.capture()
37+
expect(captor.allValues).toBe(listOf(5, 7))
3038
}
3139
}

mockito-kotlin/src/test/kotlin/MockitoTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ class MockitoTest {
162162
}
163163
}
164164

165+
@Test
166+
fun listArgCheck() {
167+
mock<Methods>().apply {
168+
closedList(listOf(Closed(), Closed()))
169+
verify(this).closedList(check {
170+
expect(it.size).toBe(2)
171+
})
172+
}
173+
}
174+
165175
@Test
166176
fun atLeastXInvocations() {
167177
mock<Methods>().apply {

0 commit comments

Comments
 (0)