diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt index 4088d18..9fe1eee 100644 --- a/tests/src/test/kotlin/test/MatchersTest.kt +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -4,446 +4,785 @@ import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import kotlinx.coroutines.test.runTest import org.junit.Test +import org.junit.experimental.runners.Enclosed +import org.junit.runner.RunWith import org.mockito.ArgumentMatcher import org.mockito.invocation.InvocationOnMock import org.mockito.kotlin.* import org.mockito.stubbing.Answer import java.io.IOException +@RunWith(Enclosed::class) class MatchersTest : TestBase() { + class AnyMatchersTest { + @Test + fun anyString() { + mock().apply { + string("") + verify(this).string(any()) + } + } - @Test - fun anyString() { - mock().apply { - string("") - verify(this).string(any()) + @Test + fun anyNullableString() { + mock().apply { + nullableString("") + verify(this).nullableString(any()) + } } - } - @Test - fun anyInt() { - mock().apply { - int(3) - verify(this).int(any()) + @Test + fun anyBoolean() { + mock().apply { + boolean(true) + verify(this).boolean(any()) + } } - } - @Test - fun anyClosedClass() { - mock().apply { - closed(Closed()) - verify(this).closed(any()) + @Test + fun anyBooleanArray() { + mock().apply { + booleanArray(booleanArrayOf(true, false, false)) + verify(this).booleanArray(any()) + } } - } - @Test - fun anyClassClosedClass() { - mock().apply { - classClosed(Closed::class.java) - verify(this).classClosed(any()) + @Test + fun anyChar() { + mock().apply { + char('3') + verify(this).char(any()) + } } - } - @Test - fun anyCoroutinesClosedClass() { - mock().apply { - runTest { - coroutinesClosed(Closed()) - verify(this@apply).coroutinesClosed(any()) + @Test + fun anyCharArray() { + mock().apply { + charArray(charArrayOf('3', '4', '5')) + verify(this).charArray(any()) } } - } - @Test - fun anyIntArray() { - mock().apply { - intArray(intArrayOf()) - verify(this).intArray(any()) + @Test + fun anyByte() { + mock().apply { + byte(3) + verify(this).byte(any()) + } } - } - @Test - fun anyClassArray() { - mock().apply { - closedArray(arrayOf(Closed())) - verify(this).closedArray(anyArray()) + @Test + fun anyByteArray() { + mock().apply { + byteArray(byteArrayOf(3, 4, 5)) + verify(this).byteArray(any()) + } } - } - @Test - fun anyNullableClassArray() { - mock().apply { - closedNullableArray(arrayOf(Closed(), null)) - verify(this).closedNullableArray(anyArray()) + @Test + fun anyShort() { + mock().apply { + short(3) + verify(this).short(any()) + } } - } - @Test - fun anyStringVararg() { - mock().apply { - closedVararg(Closed(), Closed()) - verify(this).closedVararg(anyVararg()) + @Test + fun anyShortArray() { + mock().apply { + shortArray(shortArrayOf(3, 4, 5)) + verify(this).shortArray(any()) + } } - } - @Test - fun anyVarargMatching() { - mock().apply { - whenever(varargBooleanResult(anyVararg())).thenReturn(true) - expect(varargBooleanResult()).toBe(true) + @Test + fun anyInt() { + mock().apply { + int(3) + verify(this).int(any()) + } } - } - @Test - fun anyNull_neverVerifiesAny() { - mock().apply { - nullableString(null) - verify(this, never()).nullableString(any()) + @Test + fun anyIntArray() { + mock().apply { + intArray(intArrayOf(3, 4, 5)) + verify(this).intArray(any()) + } } - } - @Test - fun anyNull_verifiesAnyOrNull() { - mock().apply { - nullableString(null) - verify(this).nullableString(anyOrNull()) + @Test + fun anyLong() { + mock().apply { + long(3) + verify(this).long(any()) + } } - } - @Test - fun anyNull_forPrimitiveBoolean() { - mock().apply { - boolean(false) - verify(this).boolean(anyOrNull()) + @Test + fun anyLongArray() { + mock().apply { + longArray(longArrayOf(3L, 4L, 5L)) + verify(this).longArray(any()) + } } - } - @Test - fun anyNull_forPrimitiveByte() { - mock().apply { - byte(3) - verify(this).byte(anyOrNull()) + @Test + fun anyFloat() { + mock().apply { + float(3f) + verify(this).float(any()) + } } - } - @Test - fun anyNull_forPrimitiveChar() { - mock().apply { - char('a') - verify(this).char(anyOrNull()) + @Test + fun anyFloatArray() { + mock().apply { + floatArray(floatArrayOf(3f, 4f, 5f)) + verify(this).floatArray(any()) + } } - } - @Test - fun anyNull_forPrimitiveShort() { - mock().apply { - short(3) - verify(this).short(anyOrNull()) + @Test + fun anyDouble() { + mock().apply { + double(3.0) + verify(this).double(any()) + } } - } - @Test - fun anyNull_forPrimitiveInt() { - mock().apply { - int(3) - verify(this).int(anyOrNull()) + @Test + fun anyDoubleArray() { + mock().apply { + doubleArray(doubleArrayOf(3.0, 4.0, 5.0)) + verify(this).doubleArray(any()) + } } - } - @Test - fun anyNull_forPrimitiveLong() { - mock().apply { - long(3) - verify(this).long(anyOrNull()) + @Test + fun anyClosedClass() { + mock().apply { + closed(Closed()) + verify(this).closed(any()) + } } - } - @Test - fun anyNull_forPrimitiveFloat() { - mock().apply { - float(3f) - verify(this).float(anyOrNull()) + @Test + fun anyClassClosedClass() { + mock().apply { + classClosed(Closed::class.java) + verify(this).classClosed(any()) + } } - } - @Test - fun anyNull_forPrimitiveDouble() { - mock().apply { - double(3.0) - verify(this).double(anyOrNull()) + @Test + fun anyCoroutinesClosedClass() { + mock().apply { + runTest { + coroutinesClosed(Closed()) + verify(this@apply).coroutinesClosed(any()) + } + } } - } - /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ - @Test - fun anyThrowableWithSingleThrowableConstructor() { - mock().apply { - throwableClass(ThrowableClass(IOException())) - verify(this).throwableClass(any()) + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ + @Test + fun anyThrowableWithSingleThrowableConstructor() { + mock().apply { + throwableClass(ThrowableClass(IOException())) + verify(this).throwableClass(any()) + } } - } - @Test - fun listArgThat() { - mock().apply { - closedList(listOf(Closed(), Closed())) - verify(this).closedList( - argThat { - size == 2 - } - ) + @Test + fun anyValueClass() { + mock().apply { + valueClass(ValueClass("Content")) + verify(this).valueClass(any()) + } } - } - @Test - fun listArgForWhich() { - mock().apply { - closedList(listOf(Closed(), Closed())) - verify(this).closedList( - argForWhich { - size == 2 - } - ) + @Test + fun anyNeverVerifiesForNullValue() { + mock().apply { + nullableString(null) + verify(this, never()).nullableString(any()) + } } } - @Test - fun listArgWhere() { - mock().apply { - closedList(listOf(Closed(), Closed())) - verify(this).closedList( - argWhere { - it.size == 2 - } - ) + class SpecialAnyMatchersTest { + @Test + fun anyClassArray() { + mock().apply { + closedArray(arrayOf(Closed())) + verify(this).closedArray(anyArray()) + } } - } - @Test - fun listArgCheck() { - mock().apply { - closedList(listOf(Closed(), Closed())) - verify(this).closedList( - check { - expect(it.size).toBe(2) - } - ) + @Test + fun anyNullableClassArray() { + mock().apply { + closedNullableArray(arrayOf(Closed(), null)) + verify(this).closedNullableArray(anyArray()) + } } - } - @Test - fun checkProperlyFails() { - mock().apply { - closedList(listOf(Closed(), Closed())) + @Test + fun anyStringVararg() { + mock().apply { + closedVararg(Closed(), Closed()) + verify(this).closedVararg(anyVararg()) + } + } - expectErrorWithMessage("Argument(s) are different!") on { - verify(this).closedList( - check { - expect(it.size).toBe(1) - } - ) + @Test + fun anyVarargMatching() { + mock().apply { + whenever(varargBooleanResult(anyVararg())).thenReturn(true) + expect(varargBooleanResult()).toBe(true) } } - } - @Test - fun checkWithNullArgument_throwsError() { - mock().apply { - nullableString(null) + @Test + fun anyValueClass_withValueClass() { + mock().apply { + valueClass(ValueClass("Content")) + verify(this).valueClass(anyValueClass()) + } + } - expectErrorWithMessage("null").on { - verify(this).nullableString(check {}) + @Test + fun anyValueClass_withNonValueClass() { + expectErrorWithMessage("kotlin.Float is not a value class.") on { + mock().apply { + float(10f) + // Should throw an error because Float is not a value class + float(anyValueClass()) + } } } - } - @Test - fun isA_withNonNullableString() { - mock().apply { - string("") - verify(this).string(isA()) + @Test + fun anyValueClass_withNestedValueClass() { + mock().apply { + nestedValueClass(NestedValueClass(ValueClass("Content"))) + verify(this).nestedValueClass(anyValueClass()) + } } } - @Test - fun isA_withNullableString() { - mock().apply { - nullableString("") - verify(this).nullableString(isA()) + class AnyOrNullMatchersTest { + @Test + fun anyOrNullString() { + mock().apply { + string("") + verify(this).string(anyOrNull()) + } } - } - @Test - fun same_withNonNullArgument() { - mock().apply { - string("") - verify(this).string(same("")) + @Test + fun anyOrNullNullableString() { + mock().apply { + nullableString("") + verify(this).nullableString(anyOrNull()) + } } - } - @Test - fun same_withNullableNonNullArgument() { - mock().apply { - nullableString("") - verify(this).nullableString(same("")) + @Test + fun anyOrNullNullableStringNullValue() { + mock().apply { + nullableString(null) + verify(this).nullableString(anyOrNull()) + } } - } - @Test - fun same_withNullArgument() { - mock().apply { - nullableString(null) - verify(this).nullableString(same(null)) + @Test + fun anyOrNullBoolean() { + mock().apply { + boolean(false) + verify(this).boolean(anyOrNull()) + } } - } - @Test - fun testVarargAnySuccess() { - /* Given */ - val t = mock() - // a matcher to check if any of the varargs was equals to "b" - val matcher = VarargAnyMatcher({ "b" == it }, String::class.java, true, false) + @Test + fun anyOrNullByte() { + mock().apply { + byte(3) + verify(this).byte(anyOrNull()) + } + } - /* When */ - whenever(t.varargBooleanResult(argThat(matcher))).thenAnswer(matcher) + @Test + fun anyOrNullChar() { + mock().apply { + char('a') + verify(this).char(anyOrNull()) + } + } - /* Then */ - expect(t.varargBooleanResult("a", "b", "c")).toBe(true) - } + @Test + fun anyOrNullShort() { + mock().apply { + short(3) + verify(this).short(anyOrNull()) + } + } - @Test - fun testVarargAnyFail() { - /* Given */ - val t = mock() - // a matcher to check if any of the varargs was equals to "d" - val matcher = VarargAnyMatcher({ "d" == it }, String::class.java, true, false) + @Test + fun anyOrNullInt() { + mock().apply { + int(3) + verify(this).int(anyOrNull()) + } + } - /* When */ - whenever(t.varargBooleanResult(argThat(matcher))).thenAnswer(matcher) + @Test + fun anyOrNullLong() { + mock().apply { + long(3) + verify(this).long(anyOrNull()) + } + } - /* Then */ - expect(t.varargBooleanResult("a", "b", "c")).toBe(false) - } + @Test + fun anyOrNullFloat() { + mock().apply { + float(3f) + verify(this).float(anyOrNull()) + } + } - /** https://github.com/nhaarman/mockito-kotlin/issues/328 */ - @Test - fun testRefEqForNonNullableParameter() { - mock().apply { - /* When */ - val array = intArrayOf(2, 3) - intArray(array) + @Test + fun anyOrNullDouble() { + mock().apply { + double(3.0) + verify(this).double(anyOrNull()) + } + } - /* Then */ - verify(this).intArray(refEq(array)) + @Test + fun anyOrNullValueClass() { + mock().apply { + valueClass(ValueClass("Content")) + verify(this).valueClass(anyOrNull()) + } } - } - @Test - fun any_forValueClass() { - mock().apply { - valueClass(ValueClass("Content")) - verify(this).valueClass(any()) + @Test + fun anyOrNullNullableValueClass() { + mock().apply { + nullableValueClass(ValueClass("Content")) + verify(this).nullableValueClass(anyOrNull()) + } } - } - @Test - fun anyOrNull_forValueClass() { - mock().apply { - nullableValueClass(ValueClass("Content")) - verify(this).nullableValueClass(anyOrNull()) + @Test + fun anyOrNullNullableValueClassNullValue() { + mock().apply { + nullableValueClass(null) + verify(this).nullableValueClass(anyOrNull()) + } } } - @Test - fun anyOrNull_forValueClass_withNull() { - mock().apply { - nullableValueClass(null) - verify(this).nullableValueClass(anyOrNull()) + class EqMatchersTest { + @Test + fun eqString() { + val value = "Value" + mock().apply { + string(value) + verify(this).string(eq(value)) + } } - } - @Test - fun anyValueClass_withValueClass() { - mock().apply { - valueClass(ValueClass("Content")) - verify(this).valueClass(anyValueClass()) + @Test + fun eqBoolean() { + val value = true + mock().apply { + boolean(value) + verify(this).boolean(eq(value)) + } } - } - @Test - fun anyValueClass_withNonValueClass() { - expectErrorWithMessage("kotlin.Float is not a value class.") on { + @Test + fun eqBooleanArray() { + val value = booleanArrayOf(true, false, false) mock().apply { - float(10f) - // Should throw an error because Float is not a value class - float(anyValueClass()) + booleanArray(value) + verify(this).booleanArray(eq(value)) } } - } - @Test - fun anyValueClass_withNestedValueClass() { - mock().apply { - nestedValueClass(NestedValueClass(ValueClass("Content"))) - verify(this).nestedValueClass(anyValueClass()) + @Test + fun eqChar() { + val value = '3' + mock().apply { + char(value) + verify(this).char(eq(value)) + } } - } - @Test - fun eq_forValueClass() { - val valueClass = ValueClass("Content") - mock().apply { - valueClass(valueClass) - verify(this).valueClass(eq(valueClass)) + @Test + fun eqCharArray() { + val value = charArrayOf('3', '4', '5') + mock().apply { + charArray(value) + verify(this).charArray(eq(value)) + } } - } - @Test - fun eq_withNestedValueClass() { - val nestedValueClass = NestedValueClass(ValueClass("Content")) - mock().apply { - nestedValueClass(nestedValueClass) - verify(this).nestedValueClass(eq(nestedValueClass)) + @Test + fun eqByte() { + val value: Byte = 3 + mock().apply { + byte(value) + verify(this).byte(eq(value)) + } } - } - @Test - fun eq_withClosedClass() { - val closedClassInstance = Closed() - mock().apply { - closed(closedClassInstance) - verify(this).closed(eq(closedClassInstance)) + @Test + fun eqByteArray() { + val value = byteArrayOf(3, 4, 5) + mock().apply { + byteArray(value) + verify(this).byteArray(eq(value)) + } + } + + @Test + fun eqShort() { + val value: Short = 3 + mock().apply { + short(value) + verify(this).short(eq(value)) + } + } + + @Test + fun eqShortArray() { + val value = shortArrayOf(3, 4, 5) + mock().apply { + shortArray(value) + verify(this).shortArray(eq(value)) + } + } + + @Test + fun eqInt() { + val value = 3 + mock().apply { + int(value) + verify(this).int(eq(value)) + } + } + + @Test + fun eqIntArray() { + val value = intArrayOf(3, 4, 5) + mock().apply { + intArray(value) + verify(this).intArray(eq(value)) + } + } + + @Test + fun eqLong() { + val value = 3L + mock().apply { + long(value) + verify(this).long(eq(value)) + } + } + + @Test + fun eqLongArray() { + val value = longArrayOf(3L, 4L, 5L) + mock().apply { + longArray(value) + verify(this).longArray(eq(value)) + } + } + + @Test + fun eqFloat() { + val value = 3f + mock().apply { + float(value) + verify(this).float(eq(value)) + } + } + + @Test + fun eqFloatArray() { + val value = floatArrayOf(3f, 4f, 5f) + mock().apply { + floatArray(value) + verify(this).floatArray(eq(value)) + } + } + + @Test + fun eqDouble() { + val value = 3.0 + mock().apply { + double(value) + verify(this).double(eq(value)) + } + } + + @Test + fun eqDoubleArray() { + val value = doubleArrayOf(3.0, 4.0, 5.0) + mock().apply { + doubleArray(value) + verify(this).doubleArray(eq(value)) + } + } + + @Test + fun eqClosedClass() { + val value = Closed() + mock().apply { + closed(value) + verify(this).closed(eq(value)) + } + } + + @Test + fun eqClassClosedClass() { + val clazz = Closed::class.java + mock().apply { + classClosed(clazz) + verify(this).classClosed(eq(clazz)) + } + } + + @Test + fun eqCoroutinesClosedClass() { + val value = Closed() + mock().apply { + runTest { + coroutinesClosed(value) + verify(this@apply).coroutinesClosed(eq(value)) + } + } + } + + @Test + fun eqClassArray() { + val value = arrayOf(Closed()) + mock().apply { + closedArray(value) + verify(this).closedArray(eq(value)) + } + } + + @Test + fun eqNullableClassArray() { + val value = arrayOf(Closed(), null) + mock().apply { + closedNullableArray(value) + verify(this).closedNullableArray(eq(value)) + } + } + + @Test + fun eqValueClass() { + val valueClass = ValueClass("Content") + mock().apply { + valueClass(valueClass) + verify(this).valueClass(eq(valueClass)) + } } - } - @Test - fun eq_withInt() { - mock().apply { - int(3) - verify(this).int(eq(3)) + @Test + fun eqNestedValueClass() { + val nestedValueClass = NestedValueClass(ValueClass("Content")) + mock().apply { + nestedValueClass(nestedValueClass) + verify(this).nestedValueClass(eq(nestedValueClass)) + } } } - /** - * a VarargMatcher implementation for varargs of type [T] that will answer with type [R] if any of the var args - * matched. Needs to keep state between matching invocations. - */ - private class VarargAnyMatcher( - private val match: ((T) -> Boolean), - private val clazz: Class, - private val success: R, - private val failure: R - ) : ArgumentMatcher, Answer { - private var anyMatched = false + class OtherMatchersTest { + @Test + fun listArgThat() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList( + argThat { + size == 2 + } + ) + } + } + + @Test + fun listArgForWhich() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList( + argForWhich { + size == 2 + } + ) + } + } + + @Test + fun listArgWhere() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList( + argWhere { + it.size == 2 + } + ) + } + } + + @Test + fun listArgCheck() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList( + check { + expect(it.size).toBe(2) + } + ) + } + } + + @Test + fun checkProperlyFails() { + mock().apply { + closedList(listOf(Closed(), Closed())) + + expectErrorWithMessage("Argument(s) are different!") on { + verify(this).closedList( + check { + expect(it.size).toBe(1) + } + ) + } + } + } + + @Test + fun checkWithNullArgument_throwsError() { + mock().apply { + nullableString(null) + + expectErrorWithMessage("null").on { + verify(this).nullableString(check {}) + } + } + } + + @Test + fun isA_withNonNullableString() { + mock().apply { + string("") + verify(this).string(isA()) + } + } + + @Test + fun isA_withNullableString() { + mock().apply { + nullableString("") + verify(this).nullableString(isA()) + } + } + + @Test + fun same_withNonNullArgument() { + mock().apply { + string("") + verify(this).string(same("")) + } + } + + @Test + fun same_withNullableNonNullArgument() { + mock().apply { + nullableString("") + verify(this).nullableString(same("")) + } + } + + @Test + fun same_withNullArgument() { + mock().apply { + nullableString(null) + verify(this).nullableString(same(null)) + } + } + + @Test + fun testVarargAnySuccess() { + /* Given */ + val t = mock() + // a matcher to check if any of the varargs was equals to "b" + val matcher = VarargAnyMatcher({ "b" == it }, String::class.java, true, false) + + /* When */ + whenever(t.varargBooleanResult(argThat(matcher))).thenAnswer(matcher) + + /* Then */ + expect(t.varargBooleanResult("a", "b", "c")).toBe(true) + } + + @Test + fun testVarargAnyFail() { + /* Given */ + val t = mock() + // a matcher to check if any of the varargs was equals to "d" + val matcher = VarargAnyMatcher({ "d" == it }, String::class.java, true, false) + + /* When */ + whenever(t.varargBooleanResult(argThat(matcher))).thenAnswer(matcher) + + /* Then */ + expect(t.varargBooleanResult("a", "b", "c")).toBe(false) + } + + /** https://github.com/nhaarman/mockito-kotlin/issues/328 */ + @Test + fun testRefEqForNonNullableParameter() { + mock().apply { + /* When */ + val array = intArrayOf(2, 3) + intArray(array) - override fun matches(t: T): Boolean { - @Suppress("UNCHECKED_CAST") // No idea how to solve this better - anyMatched = (t as Array).any(match) - return anyMatched + /* Then */ + verify(this).intArray(refEq(array)) + } } - override fun answer(i: InvocationOnMock) = if (anyMatched) success else failure + /** + * a VarargMatcher implementation for varargs of type [T] that will answer with type [R] if any of the var args + * matched. Needs to keep state between matching invocations. + */ + private class VarargAnyMatcher( + private val match: ((T) -> Boolean), + private val clazz: Class, + private val success: R, + private val failure: R + ) : ArgumentMatcher, Answer { + private var anyMatched = false + + override fun matches(t: T): Boolean { + @Suppress("UNCHECKED_CAST") // No idea how to solve this better + anyMatched = (t as Array).any(match) + return anyMatched + } + + override fun answer(i: InvocationOnMock) = if (anyMatched) success else failure - override fun type(): Class<*> = java.lang.reflect.Array.newInstance(clazz, 0).javaClass + override fun type(): Class<*> = java.lang.reflect.Array.newInstance(clazz, 0).javaClass + } } }