Skip to content

Commit

Permalink
Add nullableArgumentCaptor to be able to work with lists of nullables
Browse files Browse the repository at this point in the history
  • Loading branch information
nhaarman committed Oct 26, 2016
1 parent 7b6c5b7 commit 086d482
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,31 @@ import org.mockito.ArgumentCaptor
import kotlin.reflect.KClass

inline fun <reified T : Any> argumentCaptor(): KArgumentCaptor<T> = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
inline fun <reified T : Any> nullableArgumentCaptor(): KArgumentCaptor<T?> = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)

inline fun <reified T : Any> capture(captor: ArgumentCaptor<T>): T = captor.capture() ?: createInstance<T>()

@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()"), DeprecationLevel.ERROR)
inline fun <reified T : Any> capture(captor: KArgumentCaptor<T>): T = captor.capture()

class KArgumentCaptor<out T : Any>(private val captor: ArgumentCaptor<T>, private val tClass: KClass<T>) {
class KArgumentCaptor<out T : Any?>(private val captor: ArgumentCaptor<T>, private val tClass: KClass<*>) {

val value: T
get() = captor.value

val allValues: List<T>
get() = captor.allValues

fun capture(): T = captor.capture() ?: createInstance(tClass)
@Suppress("UNCHECKED_CAST")
fun capture(): T = captor.capture() ?: createInstance(tClass) as T
}

/**
* This method is deprecated because its behavior differs from the Java behavior.
* Instead, use [argumentCaptor] in the traditional way, or use one of
* [argThat], [argForWhich] or [check].
*/
@Deprecated("Use argumentCaptor() or argThat() instead.", ReplaceWith("check(consumer)"), DeprecationLevel.ERROR)
@Deprecated("Use argumentCaptor(), argThat() or check() instead.", ReplaceWith("check(consumer)"), DeprecationLevel.ERROR)
inline fun <reified T : Any> capture(noinline consumer: (T) -> Unit): T {
var times = 0
return argThat { if (++times == 1) consumer.invoke(this); true }
Expand Down
50 changes: 45 additions & 5 deletions mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import com.nhaarman.expect.expect
import com.nhaarman.mockito_kotlin.argumentCaptor
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.times
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.*
import org.junit.Test
import java.util.*

class ArgumentCaptorTest {

@Test
fun explicitCaptor() {
fun argumentCaptor_withSingleValue() {
/* Given */
val date: Date = mock()

Expand All @@ -22,6 +19,34 @@ class ArgumentCaptorTest {
expect(captor.value).toBe(5L)
}

@Test
fun argumentCaptor_withNullValue_usingNonNullable() {
/* Given */
val m: Methods = mock()

/* When */
m.nullableString(null)

/* Then */
val captor = argumentCaptor<String>()
verify(m).nullableString(captor.capture())
expect(captor.value).toBeNull()
}

@Test
fun argumentCaptor_withNullValue_usingNullable() {
/* Given */
val m: Methods = mock()

/* When */
m.nullableString(null)

/* Then */
val captor = nullableArgumentCaptor<String>()
verify(m).nullableString(captor.capture())
expect(captor.value).toBeNull()
}

@Test
fun argumentCaptor_multipleValues() {
/* Given */
Expand All @@ -36,4 +61,19 @@ class ArgumentCaptorTest {
verify(date, times(2)).time = captor.capture()
expect(captor.allValues).toBe(listOf(5, 7))
}

@Test
fun argumentCaptor_multipleValuesIncludingNull() {
/* Given */
val m: Methods = mock()

/* When */
m.nullableString("test")
m.nullableString(null)

/* Then */
val captor = nullableArgumentCaptor<String>()
verify(m, times(2)).nullableString(captor.capture())
expect(captor.allValues).toBe(listOf("test", null))
}
}

0 comments on commit 086d482

Please sign in to comment.