From 2f9603ae72f6e25dcd9c79ff67d281b6a10ca3e2 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 18 Jan 2016 21:48:20 +0100 Subject: Initial commit --- .gitignore | 8 + .travis.yml | 16 + LICENSE | 22 ++ README.md | 72 ++++ build.gradle | 0 gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 52271 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 164 +++++++++ gradlew.bat | 90 +++++ mockito-kotlin/build.gradle | 26 ++ .../main/kotlin/com/nhaarman/mockito_kotlin/Any.kt | 131 +++++++ .../nhaarman/mockito_kotlin/MatcherExtension.kt | 29 ++ .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 36 ++ mockito-kotlin/src/test/kotlin/AnyTest.kt | 382 +++++++++++++++++++++ mockito-kotlin/src/test/kotlin/MatcherTest.kt | 45 +++ mockito-kotlin/src/test/kotlin/MockTest.kt | 80 +++++ mockito-kotlin/src/test/kotlin/SpyTest.kt | 56 +++ settings.gradle | 2 + 18 files changed, 1165 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 mockito-kotlin/build.gradle create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt create mode 100644 mockito-kotlin/src/test/kotlin/AnyTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/MatcherTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/MockTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/SpyTest.kt create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be8403e --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.gradle +build/ + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar +*.iml + +.idea/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7467f22 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +sudo: false + +language: java + +jdk: +- oraclejdk7 + +env: + matrix: + - TERM=dumb + +install: + - true + +script: + - ./gradlew test \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8a39ffc --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2016 Niek Haarman +Copyright (c) 2007 Mockito contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e7bb62d --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# Mockito-Kotlin + +A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. + +## Download + +Download a .jar file from the [releases page](https://github.com/nhaarman/mockito-kotlin/releases). + +## Examples + +### Creating mock instances + +Due to Kotlin's [reified type parameters](https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters), if the type can be inferred, you don't have to specify it explicitly: + +**Java**: +```java +MyClass c = mock(Myclass.class); +c.doSomething(mock(MyOtherClass.class)); +``` + +**Kotlin**: +```kotlin +val c : MyClass = mock() +c.doSomething(mock()) +``` + +If the type can't be inferred, you can pass it like so: + +```kotlin +val d = mock() +``` + + +### Expecting any value + +Mockito's `any(Class)` often returns `null` for non-primitive classes. +In Kotlin, this can be a problem due to its [null-safety](https://kotlinlang.org/docs/reference/null-safety.html) feature. +This library creates non-null instances when necessary. +Again, if the type can be inferred, you don't have to specify it explicitely: + +**Java**: +```java +verify(myClass).doSomething(any(String.class)); +``` + +**Kotlin**: +```kotlin +verify(myClass).doSomething(any()); // Non-nullable parameter type is inferred +``` + +For generic arrays, use the `anyArray()` method: + +```kotlin +verify(myClass).setItems(anyArray()) +``` + +### Argument Matchers + +Using higher-order functions, you can write very clear expectations about expected values. +For example: + +**Kotlin**: +```kotlin +verify(myClass).setItems(argThat{ size == 2 }) +``` + +### Convenience functions + +Most of Mockito's static functions are available as top-level functions. +That means, IDE's like IntelliJ can easily import and autocomplete them, saving you the hassle of manually importing them. + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e69de29 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..30d399d Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..909374a --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Jan 20 23:10:29 CET 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle new file mode 100644 index 0000000..2776d2a --- /dev/null +++ b/mockito-kotlin/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'kotlin' + +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.0-beta-4589" + } +} + +repositories { + mavenCentral() + jcenter() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.0-beta-4589" + compile "org.jetbrains.kotlin:kotlin-reflect:1.0.0-beta-4589" + compile "org.mockito:mockito-core:2.0.39-beta" + + /* Tests */ + testCompile "junit:junit:4.12" + testCompile "com.nhaarman:expect.kt:0.3.0" +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt new file mode 100644 index 0000000..2dc94a1 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.nhaarman.mockito_kotlin + +import org.mockito.Answers +import org.mockito.Mockito +import org.mockito.internal.creation.MockSettingsImpl +import org.mockito.internal.util.MockUtil +import java.lang.reflect.Modifier +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type +import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.defaultType +import kotlin.reflect.jvm.javaType + +inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() +inline fun any() = any(T::class) +fun any(clzz: KClass) = Mockito.any(clzz.java) ?: createInstance(clzz) + +internal fun createInstance(kClass: KClass): T { + return createInstance(kClass.defaultType) as T +} + +@Suppress("UNCHECKED_CAST") +private fun createInstance(kType: KType): T? { + if (kType.isMarkedNullable) { + return null + } + + val javaType: Type = kType.javaType + if (javaType is ParameterizedType) { + val rawType = javaType.rawType + return createInstance(rawType as Class) + } else if (javaType is Class<*> && javaType.isPrimitive) { + return defaultPrimitive(javaType as Class) + } else if (javaType is Class<*>) { + return createInstance(javaType as Class) + } else { + return null + } +} + +@Suppress("UNCHECKED_CAST") +private fun createInstance(jClass: Class): T { + if (!Modifier.isFinal(jClass.modifiers)) { + return uncheckedMock(jClass) + } + + if (jClass.isPrimitive || jClass == String::class.java) { + return defaultPrimitive(jClass) + } + + if (jClass.isArray) { + return jClass.toArrayInstance() + } + + val constructor = jClass.constructors + .sortedBy { it.parameterTypes.size } + .first() + + val params = constructor.parameterTypes.map { createInstance(it) } + + val result: Any = when (params.size) { + 0 -> constructor.newInstance() + 1 -> constructor.newInstance(params[0]) + 2 -> constructor.newInstance(params[0], params[1]) + 3 -> constructor.newInstance(params[0], params[1], params[2]) + 4 -> constructor.newInstance(params[0], params[1], params[2], params[3]) + 5 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4]) + 6 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5]) + 7 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6]) + 8 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]) + 9 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], params[8]) + 10 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], params[8], params[9]) + else -> throw UnsupportedOperationException("Cannot create a new instance for ${jClass.canonicalName} with ${params.size} constructor parameters.") + } + + return result as T +} + +@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") +private fun defaultPrimitive(clzz: Class): T { + return when (clzz.canonicalName) { + "byte" -> 0.toByte() + "short" -> 0.toShort() + "int" -> 0 + "double" -> 0.0 + "float" -> 0f + "long" -> 0 + "java.lang.String" -> "" + else -> throw UnsupportedOperationException("Cannot create default primitive for ${clzz.canonicalName}.") + } as T +} + +/** + * Creates a mock instance of given class, without modifying or checking any internal Mockito state. + */ +@Suppress("UNCHECKED_CAST") +private fun uncheckedMock(clzz: Class): T { + val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl<*> + val creationSettings = impl.confirm(clzz) + return MockUtil().createMock(creationSettings) as T +} + +@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") +private fun Class.toArrayInstance(): T { + return when (simpleName) { + "byte[]" -> byteArrayOf() + "short[]" -> shortArrayOf() + "int[]" -> intArrayOf() + "long[]" -> longArrayOf() + "double[]" -> doubleArrayOf() + "float[]" -> floatArrayOf() + else -> throw UnsupportedOperationException("Cannot create a generic array for $simpleName. Use anyArray() instead.") + } as T +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt new file mode 100644 index 0000000..b5c65cf --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.nhaarman.mockito_kotlin + +import org.mockito.Mockito +import kotlin.reflect.KClass + +inline fun argThat(noinline predicate: T.() -> Boolean): T { + return argThat(T::class, predicate) +} + +@Suppress("UNCHECKED_CAST") +fun argThat(kClass: KClass, predicate: T.() -> Boolean): T { + return Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(kClass) +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt new file mode 100644 index 0000000..aaba02a --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.nhaarman.mockito_kotlin + +import org.mockito.Mockito +import org.mockito.verification.VerificationMode + +inline fun mock() = Mockito.mock(T::class.java) +fun spy(value: T) = Mockito.spy(value) + +fun whenever(methodCall: T) = Mockito.`when`(methodCall) +fun verify(mock: T) = Mockito.verify(mock) +fun verify(mock: T, mode: VerificationMode) = Mockito.verify(mock, mode) +fun verifyNoMoreInteractions(mock: T) = Mockito.verifyNoMoreInteractions(mock) +fun reset(mock: T) = Mockito.reset(mock) + +fun inOrder(vararg value: Any) = Mockito.inOrder(*value) +fun never() = Mockito.never() + +fun eq(value: T) = Mockito.eq(value) + +inline fun isNull(): T? = Mockito.isNull(T::class.java) diff --git a/mockito-kotlin/src/test/kotlin/AnyTest.kt b/mockito-kotlin/src/test/kotlin/AnyTest.kt new file mode 100644 index 0000000..72bc339 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/AnyTest.kt @@ -0,0 +1,382 @@ +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.anyArray +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.verify +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito + +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class AnyTest { + + private lateinit var doAnswer: Fake + + @Before + fun setup() { + /* Create an 'any' Mockito state */ + doAnswer = Mockito.doAnswer { }.`when`(mock()) + } + + @After + fun tearDown() { + /* Close `any` Mockito state */ + doAnswer.go(0) + } + + @Test + fun anyByte() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun anyShort() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun anyInt() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun anyLong() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun anyDouble() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBeIn(-0.000001..0.000001) + } + + @Test + fun anyFloat() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBeIn(-0.000001f..0.000001f) + } + + @Test + fun anyString() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBeEqualTo("") + } + + @Test + fun anyByteArray() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyShortArray() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyIntArray() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyLongArray() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyDoubleArray() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyFloatArray() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test(expected = UnsupportedOperationException::class) + fun anyClassArray_usingAny() { + /* When */ + any>() + } + + @Test + fun anyClassArray_usingAnyArray() { + /* When */ + val result = anyArray>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass_withOpenParameter() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass_withClosedParameter() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anySingleParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyTwoParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyThreeParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyFourParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyFiveParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anySixParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anySevenParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNestedSingleParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNestedTwoParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNestedThreeParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNestedFourParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNestedFiveParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNestedSixParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNestedSevenParameterizedClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyParameterizedClass() { + /* When */ + val result = any>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyNullableParameterClass() { + /* When */ + val result = any() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyStringList() { + /* When */ + val result = any>() + + /* Then */ + expect(result).toNotBeNull() + } + + open class Fake { + open fun go(arg: Any?) { + } + } + + class ClosedClass + class ClosedParameterizedClass(val fake: Fake) + class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) + + class SingleParameterClass(val first: Byte) + class TwoParameterClass(val first: Byte, val second: Short) + class ThreeParameterClass(val first: Byte, val second: Short, val third: Int) + class FourParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double) + class FiveParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float) + class SixParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long) + class SevenParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long, val seventh: String) + + class NestedSingleParameterClass(val nested: SingleParameterClass) + class NestedTwoParameterClass(val nested: TwoParameterClass) + class NestedThreeParameterClass(val nested: ThreeParameterClass) + class NestedFourParameterClass(val nested: FourParameterClass) + class NestedFiveParameterClass(val nested: FiveParameterClass) + class NestedSixParameterClass(val nested: SixParameterClass) + class NestedSevenParameterClass(val nested: SevenParameterClass) + + class ParameterizedClass(val t: T) + class NullableParameterClass(val s: String?) +} diff --git a/mockito-kotlin/src/test/kotlin/MatcherTest.kt b/mockito-kotlin/src/test/kotlin/MatcherTest.kt new file mode 100644 index 0000000..253aa58 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/MatcherTest.kt @@ -0,0 +1,45 @@ +import com.nhaarman.mockito_kotlin.argThat +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test + +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class MatcherTest { + + @Test + fun argThat() { + /* Given */ + val testClass: TestClass = mock() + + /* When */ + testClass.go(listOf("test")) + + /* Then */ + verify(testClass).go( + argThat { + size == 1 + get(0) == "test" + } + ) + } + + interface TestClass { + + fun go(v: List) + } +} diff --git a/mockito-kotlin/src/test/kotlin/MockTest.kt b/mockito-kotlin/src/test/kotlin/MockTest.kt new file mode 100644 index 0000000..dad469f --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/MockTest.kt @@ -0,0 +1,80 @@ +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.mock +import org.junit.Test +import org.mockito.exceptions.base.MockitoException + +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class MockTest { + + private lateinit var propertyInterfaceVariable: MyInterface + private lateinit var propertyClassVariable: MyClass + + @Test + fun localInterfaceValue() { + /* When */ + val instance: MyInterface = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyInterfaceVariable() { + /* When */ + propertyInterfaceVariable = mock() + + /* Then */ + expect(propertyInterfaceVariable).toNotBeNull() + } + + @Test + fun localClassValue() { + /* When */ + val instance: MyClass = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyClassVariable() { + /* When */ + propertyClassVariable = mock() + + /* Then */ + expect(propertyClassVariable).toNotBeNull() + } + + @Test + fun untypedVariable() { + /* When */ + val instance = mock() + + expect(instance).toNotBeNull() + } + + @Test(expected = MockitoException::class) + fun closedClass() { + mock() + } + + private interface MyInterface + private open class MyClass + private class ClosedClass +} + diff --git a/mockito-kotlin/src/test/kotlin/SpyTest.kt b/mockito-kotlin/src/test/kotlin/SpyTest.kt new file mode 100644 index 0000000..ec2d4ef --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/SpyTest.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.spy +import org.junit.Test +import org.mockito.exceptions.base.MockitoException + +class SpyTest { + + private val interfaceInstance: MyInterface = MyClass() + private val openClassInstance: MyClass = MyClass() + private val closedClassInstance: ClosedClass = ClosedClass() + + @Test + fun spyInterfaceInstance() { + /* When */ + val result = spy(interfaceInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun spyOpenClassInstance() { + /* When */ + val result = spy(openClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test(expected = MockitoException::class) + fun spyClosedClassInstance() { + /* When */ + spy(closedClassInstance) + } + + private interface MyInterface + private open class MyClass : MyInterface + private class ClosedClass +} + diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..3e1090c --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +include 'mockito-kotlin' + -- cgit v1.2.3 From b113029dd831bcae0c07402aef6f4310bdac6626 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 16:12:48 +0100 Subject: Upload to Bintray --- build.gradle | 7 ++++ gradle.properties | 26 +++++++++++++ gradle/scripts/tagging.gradle | 22 +++++++++++ mockito-kotlin/build.gradle | 45 ++++++++++++++++++++++ .../main/kotlin/com/nhaarman/mockito_kotlin/Any.kt | 29 +++++++++----- .../nhaarman/mockito_kotlin/MatcherExtension.kt | 29 +++++++++----- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 29 +++++++++----- mockito-kotlin/src/test/kotlin/AnyTest.kt | 25 ++++++++++++ mockito-kotlin/src/test/kotlin/MatcherTest.kt | 25 ++++++++++++ mockito-kotlin/src/test/kotlin/MockTest.kt | 25 ++++++++++++ mockito-kotlin/src/test/kotlin/SpyTest.kt | 25 ++++++++++++ 11 files changed, 257 insertions(+), 30 deletions(-) create mode 100644 gradle.properties create mode 100644 gradle/scripts/tagging.gradle diff --git a/build.gradle b/build.gradle index e69de29..cc7ac90 100644 --- a/build.gradle +++ b/build.gradle @@ -0,0 +1,7 @@ +plugins { + id "com.jfrog.bintray" version "1.5" +} +apply plugin: 'maven' +apply plugin: 'maven-publish' + +apply from: 'gradle/scripts/tagging.gradle' diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..278ac4e --- /dev/null +++ b/gradle.properties @@ -0,0 +1,26 @@ +# +# The MIT License +# +# Copyright (c) 2016 Niek Haarman +# Copyright (c) 2007 Mockito contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +isRelease = false diff --git a/gradle/scripts/tagging.gradle b/gradle/scripts/tagging.gradle new file mode 100644 index 0000000..e7b4281 --- /dev/null +++ b/gradle/scripts/tagging.gradle @@ -0,0 +1,22 @@ +new ByteArrayOutputStream().withStream { os -> + + exec { + commandLine 'git', 'describe' + standardOutput = os + } + + String tag = os.toString().trim(); + if (tag.length() == 0) { + tag = "0.0.0" + } else if (tag.indexOf('-') != -1 && tag.length() > tag.indexOf('-') + 1 && tag.charAt(tag.indexOf('-') + 1).isDigit()) { + tag = tag.substring(0, tag.indexOf('-')); + } + + ext.versionName = tag; + + if (isRelease == 'false') { + int lastNumber = Integer.parseInt(tag.substring(tag.size() - 1)) + ext.versionName = tag.substring(0, tag.size() - 1) + (lastNumber + 1) + "-SNAPSHOT"; + } +} + diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 2776d2a..352a9a5 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -24,3 +24,48 @@ dependencies { testCompile "junit:junit:4.12" testCompile "com.nhaarman:expect.kt:0.3.0" } + +publishing { + publications { + MyPublication(MavenPublication) { + from components.java + artifact javadocJar + artifact sourcesJar + + groupId 'com.nhaarman' + artifactId 'mockito-kotlin' + version '1.0' + } + } +} + +bintray { + user = hasProperty('bintray_user') ? bintray_user : System.getenv('BINTRAY_USER') + key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') + publications = ['MyPublication'] + + pkg { + repo = 'maven' + name = "Mockito-Kotlin" + desc = "Using Mockito with Kotlin" + + licenses = ['Apache-2.0'] + vcsUrl = 'https://github.com/bintray/gradle-bintray-plugin.git' + + version { + name = rootProject.ext.versionName + desc = 'Using Mockito with Kotlin' + vcsTag = rootProject.ext.versionName + } + } +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from 'build/docs/javadoc' +} + +task sourcesJar(type: Jar) { + from sourceSets.main.allSource + classifier = 'sources' +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt index 2dc94a1..f6828f4 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt @@ -1,17 +1,26 @@ /* - * Copyright 2016 Niek Haarman + * The MIT License * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors * - * http://www.apache.org/licenses/LICENSE-2.0 + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ package com.nhaarman.mockito_kotlin diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt index b5c65cf..041c7c2 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt @@ -1,17 +1,26 @@ /* - * Copyright 2016 Niek Haarman + * The MIT License * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors * - * http://www.apache.org/licenses/LICENSE-2.0 + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ package com.nhaarman.mockito_kotlin diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index aaba02a..833cf86 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -1,17 +1,26 @@ /* - * Copyright 2016 Niek Haarman + * The MIT License * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors * - * http://www.apache.org/licenses/LICENSE-2.0 + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ package com.nhaarman.mockito_kotlin diff --git a/mockito-kotlin/src/test/kotlin/AnyTest.kt b/mockito-kotlin/src/test/kotlin/AnyTest.kt index 72bc339..0994f73 100644 --- a/mockito-kotlin/src/test/kotlin/AnyTest.kt +++ b/mockito-kotlin/src/test/kotlin/AnyTest.kt @@ -1,3 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.any import com.nhaarman.mockito_kotlin.anyArray diff --git a/mockito-kotlin/src/test/kotlin/MatcherTest.kt b/mockito-kotlin/src/test/kotlin/MatcherTest.kt index 253aa58..cb970c2 100644 --- a/mockito-kotlin/src/test/kotlin/MatcherTest.kt +++ b/mockito-kotlin/src/test/kotlin/MatcherTest.kt @@ -1,3 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + import com.nhaarman.mockito_kotlin.argThat import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.verify diff --git a/mockito-kotlin/src/test/kotlin/MockTest.kt b/mockito-kotlin/src/test/kotlin/MockTest.kt index dad469f..6e5b74d 100644 --- a/mockito-kotlin/src/test/kotlin/MockTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockTest.kt @@ -1,3 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.mock import org.junit.Test diff --git a/mockito-kotlin/src/test/kotlin/SpyTest.kt b/mockito-kotlin/src/test/kotlin/SpyTest.kt index ec2d4ef..04f64af 100644 --- a/mockito-kotlin/src/test/kotlin/SpyTest.kt +++ b/mockito-kotlin/src/test/kotlin/SpyTest.kt @@ -1,3 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /* * Copyright 2016 Niek Haarman * -- cgit v1.2.3 From b5a4e878dce82a59bdef46d7b94f5599961d0613 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 16:37:20 +0100 Subject: Support enums --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt | 4 ++++ mockito-kotlin/src/test/kotlin/AnyTest.kt | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt index f6828f4..b310747 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt @@ -74,6 +74,10 @@ private fun createInstance(jClass: Class): T { return defaultPrimitive(jClass) } + if (jClass.isEnum) { + return jClass.enumConstants.first() + } + if (jClass.isArray) { return jClass.toArrayInstance() } diff --git a/mockito-kotlin/src/test/kotlin/AnyTest.kt b/mockito-kotlin/src/test/kotlin/AnyTest.kt index 0994f73..83585de 100644 --- a/mockito-kotlin/src/test/kotlin/AnyTest.kt +++ b/mockito-kotlin/src/test/kotlin/AnyTest.kt @@ -27,7 +27,6 @@ import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.any import com.nhaarman.mockito_kotlin.anyArray import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.verify import org.junit.After import org.junit.Before import org.junit.Test @@ -377,6 +376,15 @@ class AnyTest { expect(result).toNotBeNull() } + @Test + fun anyEnum() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBe(MyEnum.VALUE) + } + open class Fake { open fun go(arg: Any?) { } @@ -404,4 +412,6 @@ class AnyTest { class ParameterizedClass(val t: T) class NullableParameterClass(val s: String?) + + enum class MyEnum { VALUE, ANOTHER_VALUE } } -- cgit v1.2.3 From 139d47cdb0e277499c64a1b9a60450c38db41abb Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 16:45:12 +0100 Subject: Proper version names --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 352a9a5..1802b05 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -34,7 +34,7 @@ publishing { groupId 'com.nhaarman' artifactId 'mockito-kotlin' - version '1.0' + version rootProject.ext.versionName } } } -- cgit v1.2.3 From 886cad654d434e00de0a1c115bdfe9732b1c23c0 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 16:45:12 +0100 Subject: Proper version names --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 352a9a5..1802b05 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -34,7 +34,7 @@ publishing { groupId 'com.nhaarman' artifactId 'mockito-kotlin' - version '1.0' + version rootProject.ext.versionName } } } -- cgit v1.2.3 From 92bb350222087570831f9045374c3879156ddd90 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 16:40:29 +0100 Subject: Cache Travis dependencies --- .travis.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7467f22..fce01cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,15 @@ install: - true script: - - ./gradlew test \ No newline at end of file + - ./gradlew test + +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties.lock + - rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties +cache: + directories: + - $HOME/.gradle/caches + - $HOME/.gradle/daemon + - $HOME/.gradle/native + - $HOME/.gradle/wrapper \ No newline at end of file -- cgit v1.2.3 From ad964f7d347a1cea3b09c106b6f65f0ef2ba78c4 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 17:02:49 +0100 Subject: Update README.md --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e7bb62d..51b675d 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,19 @@ A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. -## Download - -Download a .jar file from the [releases page](https://github.com/nhaarman/mockito-kotlin/releases). +## Install + +Mockito-Kotlin is available on JCenter. +For Gradle users, add the following to your `build.gradle`: + +```groovy +repositories { + jcenter() +} +dependencies { + testCompile "com.nhaarman:mockito-kotlin:x.x.x" +} +``` ## Examples -- cgit v1.2.3 From b40c9ae057959f924723b3cd6d2a31aac857e5eb Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 17:04:05 +0100 Subject: Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51b675d..2948f66 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Mockito-Kotlin +[ ![Download](https://api.bintray.com/packages/nhaarman/maven/Mockito-Kotlin/images/download.svg) ](https://bintray.com/nhaarman/maven/Mockito-Kotlin/_latestVersion) A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. -- cgit v1.2.3 From 9f1df2d88c9b5aaf4874d1d66ccccf1e3fc089d8 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 17:27:02 +0100 Subject: Make sure 'eq' does not return null --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 4 +- mockito-kotlin/src/test/kotlin/AnyTest.kt | 5 - mockito-kotlin/src/test/kotlin/EqTest.kt | 126 +++++++++++++++++++++ mockito-kotlin/src/test/kotlin/Fake.kt | 29 +++++ 4 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 mockito-kotlin/src/test/kotlin/EqTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/Fake.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 833cf86..b3e77d6 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -27,6 +27,7 @@ package com.nhaarman.mockito_kotlin import org.mockito.Mockito import org.mockito.verification.VerificationMode +import kotlin.reflect.KClass inline fun mock() = Mockito.mock(T::class.java) fun spy(value: T) = Mockito.spy(value) @@ -40,6 +41,7 @@ fun reset(mock: T) = Mockito.reset(mock) fun inOrder(vararg value: Any) = Mockito.inOrder(*value) fun never() = Mockito.never() -fun eq(value: T) = Mockito.eq(value) +inline fun eq(value: T) = eq(value, T::class) +fun eq(value: T, kClass: KClass) = Mockito.eq(value) ?: createInstance(kClass) inline fun isNull(): T? = Mockito.isNull(T::class.java) diff --git a/mockito-kotlin/src/test/kotlin/AnyTest.kt b/mockito-kotlin/src/test/kotlin/AnyTest.kt index 83585de..85057ff 100644 --- a/mockito-kotlin/src/test/kotlin/AnyTest.kt +++ b/mockito-kotlin/src/test/kotlin/AnyTest.kt @@ -385,11 +385,6 @@ class AnyTest { expect(result).toBe(MyEnum.VALUE) } - open class Fake { - open fun go(arg: Any?) { - } - } - class ClosedClass class ClosedParameterizedClass(val fake: Fake) class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) diff --git a/mockito-kotlin/src/test/kotlin/EqTest.kt b/mockito-kotlin/src/test/kotlin/EqTest.kt new file mode 100644 index 0000000..16554db --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/EqTest.kt @@ -0,0 +1,126 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* + * Copyright 2016 Niek Haarman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.eq +import com.nhaarman.mockito_kotlin.mock +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito + +class EqTest { + + private val interfaceInstance: MyInterface = MyClass() + private val openClassInstance: MyClass = MyClass() + private val closedClassInstance: ClosedClass = ClosedClass() + + private lateinit var doAnswer: Fake + + @Before + fun setup() { + /* Create a proper Mockito state */ + doAnswer = Mockito.doAnswer { }.`when`(mock()) + } + + @After + fun tearDown() { + /* Close `any` Mockito state */ + doAnswer.go(0) + } + + @Test + fun eqInterfaceInstance() { + /* When */ + val result = eq(interfaceInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun eqOpenClassInstance() { + /* When */ + val result = eq(openClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun eqClosedClassInstance() { + /* When */ + val result = eq(closedClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + private interface MyInterface + private open class MyClass : MyInterface + class ClosedClass +} + diff --git a/mockito-kotlin/src/test/kotlin/Fake.kt b/mockito-kotlin/src/test/kotlin/Fake.kt new file mode 100644 index 0000000..7aa9743 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/Fake.kt @@ -0,0 +1,29 @@ +/* +* The MIT License +* +* Copyright (c) 2016 Niek Haarman +* Copyright (c) 2007 Mockito contributors +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +open class Fake { + open fun go(arg: Any?) { + } +} \ No newline at end of file -- cgit v1.2.3 From 985679860ee08162dd533ecef6e0e882959fc67e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 17:28:48 +0100 Subject: Proper license --- mockito-kotlin/build.gradle | 2 +- mockito-kotlin/src/test/kotlin/AnyTest.kt | 16 ----------- mockito-kotlin/src/test/kotlin/EqTest.kt | 41 --------------------------- mockito-kotlin/src/test/kotlin/MatcherTest.kt | 16 ----------- mockito-kotlin/src/test/kotlin/MockTest.kt | 16 ----------- mockito-kotlin/src/test/kotlin/SpyTest.kt | 16 ----------- 6 files changed, 1 insertion(+), 106 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 1802b05..acfa773 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -49,7 +49,7 @@ bintray { name = "Mockito-Kotlin" desc = "Using Mockito with Kotlin" - licenses = ['Apache-2.0'] + licenses = ['MIT'] vcsUrl = 'https://github.com/bintray/gradle-bintray-plugin.git' version { diff --git a/mockito-kotlin/src/test/kotlin/AnyTest.kt b/mockito-kotlin/src/test/kotlin/AnyTest.kt index 85057ff..d683947 100644 --- a/mockito-kotlin/src/test/kotlin/AnyTest.kt +++ b/mockito-kotlin/src/test/kotlin/AnyTest.kt @@ -32,22 +32,6 @@ import org.junit.Before import org.junit.Test import org.mockito.Mockito -/* - * Copyright 2016 Niek Haarman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - class AnyTest { private lateinit var doAnswer: Fake diff --git a/mockito-kotlin/src/test/kotlin/EqTest.kt b/mockito-kotlin/src/test/kotlin/EqTest.kt index 16554db..dd10766 100644 --- a/mockito-kotlin/src/test/kotlin/EqTest.kt +++ b/mockito-kotlin/src/test/kotlin/EqTest.kt @@ -23,47 +23,6 @@ * THE SOFTWARE. */ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* - * Copyright 2016 Niek Haarman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.eq import com.nhaarman.mockito_kotlin.mock diff --git a/mockito-kotlin/src/test/kotlin/MatcherTest.kt b/mockito-kotlin/src/test/kotlin/MatcherTest.kt index cb970c2..770c67f 100644 --- a/mockito-kotlin/src/test/kotlin/MatcherTest.kt +++ b/mockito-kotlin/src/test/kotlin/MatcherTest.kt @@ -28,22 +28,6 @@ import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.verify import org.junit.Test -/* - * Copyright 2016 Niek Haarman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - class MatcherTest { @Test diff --git a/mockito-kotlin/src/test/kotlin/MockTest.kt b/mockito-kotlin/src/test/kotlin/MockTest.kt index 6e5b74d..0ba7285 100644 --- a/mockito-kotlin/src/test/kotlin/MockTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockTest.kt @@ -28,22 +28,6 @@ import com.nhaarman.mockito_kotlin.mock import org.junit.Test import org.mockito.exceptions.base.MockitoException -/* - * Copyright 2016 Niek Haarman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - class MockTest { private lateinit var propertyInterfaceVariable: MyInterface diff --git a/mockito-kotlin/src/test/kotlin/SpyTest.kt b/mockito-kotlin/src/test/kotlin/SpyTest.kt index 04f64af..e2cc487 100644 --- a/mockito-kotlin/src/test/kotlin/SpyTest.kt +++ b/mockito-kotlin/src/test/kotlin/SpyTest.kt @@ -23,22 +23,6 @@ * THE SOFTWARE. */ -/* - * Copyright 2016 Niek Haarman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.spy import org.junit.Test -- cgit v1.2.3 From 65d6a5f22fd010b1ab5d00c820ed0be36ba9764c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 17:48:58 +0100 Subject: Support object instances --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt | 4 ++++ mockito-kotlin/src/test/kotlin/AnyTest.kt | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt index b310747..84420d6 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt @@ -82,6 +82,10 @@ private fun createInstance(jClass: Class): T { return jClass.toArrayInstance() } + jClass.kotlin.objectInstance?.let { + return it + } + val constructor = jClass.constructors .sortedBy { it.parameterTypes.size } .first() diff --git a/mockito-kotlin/src/test/kotlin/AnyTest.kt b/mockito-kotlin/src/test/kotlin/AnyTest.kt index d683947..f2d056b 100644 --- a/mockito-kotlin/src/test/kotlin/AnyTest.kt +++ b/mockito-kotlin/src/test/kotlin/AnyTest.kt @@ -369,6 +369,15 @@ class AnyTest { expect(result).toBe(MyEnum.VALUE) } + @Test + fun anyUnit() { + /* When */ + val result = any() + + /* Then */ + expect(result).toBe(Unit) + } + class ClosedClass class ClosedParameterizedClass(val fake: Fake) class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) -- cgit v1.2.3 From a873fa74104885e25244572c9709a6b55bd3bf0f Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 20:45:30 +0100 Subject: Support private classes --- mockito-kotlin/build.gradle | 2 +- .../main/kotlin/com/nhaarman/mockito_kotlin/Any.kt | 148 -------- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 134 +++++++ .../nhaarman/mockito_kotlin/MatcherExtension.kt | 38 -- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 12 +- mockito-kotlin/src/test/kotlin/AnyTest.kt | 405 --------------------- .../src/test/kotlin/CreateInstanceTest.kt | 388 ++++++++++++++++++++ mockito-kotlin/src/test/kotlin/SpyTest.kt | 8 + 8 files changed, 540 insertions(+), 595 deletions(-) delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt delete mode 100644 mockito-kotlin/src/test/kotlin/AnyTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index acfa773..1b28258 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -68,4 +68,4 @@ task javadocJar(type: Jar, dependsOn: javadoc) { task sourcesJar(type: Jar) { from sourceSets.main.allSource classifier = 'sources' -} \ No newline at end of file +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt deleted file mode 100644 index 84420d6..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Any.kt +++ /dev/null @@ -1,148 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -import org.mockito.Answers -import org.mockito.Mockito -import org.mockito.internal.creation.MockSettingsImpl -import org.mockito.internal.util.MockUtil -import java.lang.reflect.Modifier -import java.lang.reflect.ParameterizedType -import java.lang.reflect.Type -import kotlin.reflect.KClass -import kotlin.reflect.KType -import kotlin.reflect.defaultType -import kotlin.reflect.jvm.javaType - -inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() -inline fun any() = any(T::class) -fun any(clzz: KClass) = Mockito.any(clzz.java) ?: createInstance(clzz) - -internal fun createInstance(kClass: KClass): T { - return createInstance(kClass.defaultType) as T -} - -@Suppress("UNCHECKED_CAST") -private fun createInstance(kType: KType): T? { - if (kType.isMarkedNullable) { - return null - } - - val javaType: Type = kType.javaType - if (javaType is ParameterizedType) { - val rawType = javaType.rawType - return createInstance(rawType as Class) - } else if (javaType is Class<*> && javaType.isPrimitive) { - return defaultPrimitive(javaType as Class) - } else if (javaType is Class<*>) { - return createInstance(javaType as Class) - } else { - return null - } -} - -@Suppress("UNCHECKED_CAST") -private fun createInstance(jClass: Class): T { - if (!Modifier.isFinal(jClass.modifiers)) { - return uncheckedMock(jClass) - } - - if (jClass.isPrimitive || jClass == String::class.java) { - return defaultPrimitive(jClass) - } - - if (jClass.isEnum) { - return jClass.enumConstants.first() - } - - if (jClass.isArray) { - return jClass.toArrayInstance() - } - - jClass.kotlin.objectInstance?.let { - return it - } - - val constructor = jClass.constructors - .sortedBy { it.parameterTypes.size } - .first() - - val params = constructor.parameterTypes.map { createInstance(it) } - - val result: Any = when (params.size) { - 0 -> constructor.newInstance() - 1 -> constructor.newInstance(params[0]) - 2 -> constructor.newInstance(params[0], params[1]) - 3 -> constructor.newInstance(params[0], params[1], params[2]) - 4 -> constructor.newInstance(params[0], params[1], params[2], params[3]) - 5 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4]) - 6 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5]) - 7 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6]) - 8 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]) - 9 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], params[8]) - 10 -> constructor.newInstance(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], params[8], params[9]) - else -> throw UnsupportedOperationException("Cannot create a new instance for ${jClass.canonicalName} with ${params.size} constructor parameters.") - } - - return result as T -} - -@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") -private fun defaultPrimitive(clzz: Class): T { - return when (clzz.canonicalName) { - "byte" -> 0.toByte() - "short" -> 0.toShort() - "int" -> 0 - "double" -> 0.0 - "float" -> 0f - "long" -> 0 - "java.lang.String" -> "" - else -> throw UnsupportedOperationException("Cannot create default primitive for ${clzz.canonicalName}.") - } as T -} - -/** - * Creates a mock instance of given class, without modifying or checking any internal Mockito state. - */ -@Suppress("UNCHECKED_CAST") -private fun uncheckedMock(clzz: Class): T { - val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl<*> - val creationSettings = impl.confirm(clzz) - return MockUtil().createMock(creationSettings) as T -} - -@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") -private fun Class.toArrayInstance(): T { - return when (simpleName) { - "byte[]" -> byteArrayOf() - "short[]" -> shortArrayOf() - "int[]" -> intArrayOf() - "long[]" -> longArrayOf() - "double[]" -> doubleArrayOf() - "float[]" -> floatArrayOf() - else -> throw UnsupportedOperationException("Cannot create a generic array for $simpleName. Use anyArray() instead.") - } as T -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt new file mode 100644 index 0000000..f2abb61 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -0,0 +1,134 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockito_kotlin + +import org.mockito.Answers +import org.mockito.internal.creation.MockSettingsImpl +import org.mockito.internal.util.MockUtil +import java.lang.reflect.Modifier +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type +import kotlin.reflect.KClass +import kotlin.reflect.KFunction +import kotlin.reflect.KType +import kotlin.reflect.defaultType +import kotlin.reflect.jvm.isAccessible +import kotlin.reflect.jvm.javaType + +/** + * A collection of functions that tries to create an instance of + * classes to avoid NPE's when using Mockito with Kotlin. + */ + +inline fun createArrayInstance() = arrayOf() + +inline fun createInstance() = createInstance(T::class) + +fun createInstance(kClass: KClass): T { + return when { + kClass.hasObjectInstance() -> kClass.objectInstance!! + kClass.isMockable() -> kClass.java.uncheckedMock() + kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() + kClass.isEnum() -> kClass.java.enumConstants.first() + kClass.isArray() -> kClass.toArrayInstance() + else -> kClass.constructors.first().newInstance() + } +} + +@Suppress("SENSELESS_COMPARISON") +private fun KClass<*>.hasObjectInstance() = objectInstance != null + +private fun KClass<*>.isMockable() = !Modifier.isFinal(java.modifiers) +private fun KClass<*>.isEnum() = java.isEnum +private fun KClass<*>.isArray() = java.isArray +private fun KClass<*>.isPrimitive() = + java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf( + "Byte", + "Short", + "Int", + "Double", + "Float", + "Long", + "String" + ) + +@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") +private fun KClass.toDefaultPrimitiveValue(): T { + return when (simpleName) { + "Byte" -> 0.toByte() + "Short" -> 0.toShort() + "Int" -> 0 + "Double" -> 0.0 + "Float" -> 0f + "Long" -> 0 + "String" -> "" + else -> throw UnsupportedOperationException("Cannot create default primitive for $simpleName.") + } as T +} + +@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") +private fun KClass.toArrayInstance(): T { + return when (simpleName) { + "ByteArray" -> byteArrayOf() + "ShortArray" -> shortArrayOf() + "IntArray" -> intArrayOf() + "LongArray" -> longArrayOf() + "DoubleArray" -> doubleArrayOf() + "FloatArray" -> floatArrayOf() + else -> throw UnsupportedOperationException("Cannot create a generic array for $simpleName. Use createArrayInstance() instead.") + } as T +} + +private fun KFunction.newInstance(): T { + isAccessible = true + return callBy(parameters.toMap { + it to it.type.createNullableInstance() + }) +} + +@Suppress("UNCHECKED_CAST") +private fun KType.createNullableInstance(): T? { + if (isMarkedNullable) { + return null + } + + val javaType: Type = javaType + return when (javaType) { + is ParameterizedType -> (javaType.rawType as Class).uncheckedMock() + is Class<*> -> createInstance((javaType as Class).kotlin) + else -> null + } +} + +/** + * Creates a mock instance of given class, without modifying or checking any internal Mockito state. + */ +@Suppress("UNCHECKED_CAST") +private fun Class.uncheckedMock(): T { + val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl<*> + val creationSettings = impl.confirm(this) + return MockUtil().createMock(creationSettings) as T +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt deleted file mode 100644 index 041c7c2..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MatcherExtension.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -import org.mockito.Mockito -import kotlin.reflect.KClass - -inline fun argThat(noinline predicate: T.() -> Boolean): T { - return argThat(T::class, predicate) -} - -@Suppress("UNCHECKED_CAST") -fun argThat(kClass: KClass, predicate: T.() -> Boolean): T { - return Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(kClass) -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index b3e77d6..3d09323 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -41,7 +41,13 @@ fun reset(mock: T) = Mockito.reset(mock) fun inOrder(vararg value: Any) = Mockito.inOrder(*value) fun never() = Mockito.never() -inline fun eq(value: T) = eq(value, T::class) -fun eq(value: T, kClass: KClass) = Mockito.eq(value) ?: createInstance(kClass) - +inline fun eq(value: T) = Mockito.eq(value) ?: createInstance() +inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() +inline fun any() = Mockito.any(T::class.java) ?: createInstance() inline fun isNull(): T? = Mockito.isNull(T::class.java) + +inline fun argThat(noinline predicate: T.() -> Boolean) = argThat(T::class, predicate) + +@Suppress("UNCHECKED_CAST") +fun argThat(kClass: KClass, predicate: T.() -> Boolean) + = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(kClass) diff --git a/mockito-kotlin/src/test/kotlin/AnyTest.kt b/mockito-kotlin/src/test/kotlin/AnyTest.kt deleted file mode 100644 index f2d056b..0000000 --- a/mockito-kotlin/src/test/kotlin/AnyTest.kt +++ /dev/null @@ -1,405 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.any -import com.nhaarman.mockito_kotlin.anyArray -import com.nhaarman.mockito_kotlin.mock -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.mockito.Mockito - -class AnyTest { - - private lateinit var doAnswer: Fake - - @Before - fun setup() { - /* Create an 'any' Mockito state */ - doAnswer = Mockito.doAnswer { }.`when`(mock()) - } - - @After - fun tearDown() { - /* Close `any` Mockito state */ - doAnswer.go(0) - } - - @Test - fun anyByte() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun anyShort() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun anyInt() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun anyLong() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun anyDouble() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBeIn(-0.000001..0.000001) - } - - @Test - fun anyFloat() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBeIn(-0.000001f..0.000001f) - } - - @Test - fun anyString() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBeEqualTo("") - } - - @Test - fun anyByteArray() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyShortArray() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyIntArray() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyLongArray() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyDoubleArray() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyFloatArray() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test(expected = UnsupportedOperationException::class) - fun anyClassArray_usingAny() { - /* When */ - any>() - } - - @Test - fun anyClassArray_usingAnyArray() { - /* When */ - val result = anyArray>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyClosedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyClosedClass_withOpenParameter() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyClosedClass_withClosedParameter() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anySingleParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyTwoParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyThreeParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyFourParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyFiveParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anySixParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anySevenParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNestedSingleParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNestedTwoParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNestedThreeParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNestedFourParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNestedFiveParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNestedSixParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNestedSevenParameterizedClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyParameterizedClass() { - /* When */ - val result = any>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyNullableParameterClass() { - /* When */ - val result = any() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyStringList() { - /* When */ - val result = any>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyEnum() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBe(MyEnum.VALUE) - } - - @Test - fun anyUnit() { - /* When */ - val result = any() - - /* Then */ - expect(result).toBe(Unit) - } - - class ClosedClass - class ClosedParameterizedClass(val fake: Fake) - class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) - - class SingleParameterClass(val first: Byte) - class TwoParameterClass(val first: Byte, val second: Short) - class ThreeParameterClass(val first: Byte, val second: Short, val third: Int) - class FourParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double) - class FiveParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float) - class SixParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long) - class SevenParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long, val seventh: String) - - class NestedSingleParameterClass(val nested: SingleParameterClass) - class NestedTwoParameterClass(val nested: TwoParameterClass) - class NestedThreeParameterClass(val nested: ThreeParameterClass) - class NestedFourParameterClass(val nested: FourParameterClass) - class NestedFiveParameterClass(val nested: FiveParameterClass) - class NestedSixParameterClass(val nested: SixParameterClass) - class NestedSevenParameterClass(val nested: SevenParameterClass) - - class ParameterizedClass(val t: T) - class NullableParameterClass(val s: String?) - - enum class MyEnum { VALUE, ANOTHER_VALUE } -} diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt new file mode 100644 index 0000000..d2ea568 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -0,0 +1,388 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.createInstance +import org.junit.Test + +class CreateInstanceTest { + + @Test + fun byte() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun short() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun int() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun long() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun double() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBeIn(-0.000001..0.000001) + } + + @Test + fun float() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBeIn(-0.000001f..0.000001f) + } + + @Test + fun string() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBeEqualTo("") + } + + @Test + fun byteArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun shortArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun intArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun longArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun doubleArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun floatArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test(expected = UnsupportedOperationException::class) + fun classArray_usingAny() { + /* When */ + createInstance>() + } + + @Test + fun closedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun closedClass_withOpenParameter() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun closedClass_withClosedParameter() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun singleParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun twoParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun threeParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun fourParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun fiveParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun sixParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun sevenParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedSingleParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedTwoParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedThreeParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedFourParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedFiveParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedSixParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedSevenParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun parameterizedClass() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nullableParameterClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun stringList() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun enum() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(MyEnum.VALUE) + } + + @Test + fun unit() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(Unit) + } + + @Test + fun privateClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + private class PrivateClass private constructor(val data: String) + + class ClosedClass + class ClosedParameterizedClass(val fake: Fake) + class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) + + class SingleParameterClass(val first: Byte) + class TwoParameterClass(val first: Byte, val second: Short) + class ThreeParameterClass(val first: Byte, val second: Short, val third: Int) + class FourParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double) + class FiveParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float) + class SixParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long) + class SevenParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long, val seventh: String) + + class NestedSingleParameterClass(val nested: SingleParameterClass) + class NestedTwoParameterClass(val nested: TwoParameterClass) + class NestedThreeParameterClass(val nested: ThreeParameterClass) + class NestedFourParameterClass(val nested: FourParameterClass) + class NestedFiveParameterClass(val nested: FiveParameterClass) + class NestedSixParameterClass(val nested: SixParameterClass) + class NestedSevenParameterClass(val nested: SevenParameterClass) + + class ParameterizedClass(val t: T) + class NullableParameterClass(val s: String?) + + enum class MyEnum { VALUE, ANOTHER_VALUE } +} diff --git a/mockito-kotlin/src/test/kotlin/SpyTest.kt b/mockito-kotlin/src/test/kotlin/SpyTest.kt index e2cc487..860abf9 100644 --- a/mockito-kotlin/src/test/kotlin/SpyTest.kt +++ b/mockito-kotlin/src/test/kotlin/SpyTest.kt @@ -25,7 +25,9 @@ import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.spy +import org.junit.After import org.junit.Test +import org.mockito.Mockito import org.mockito.exceptions.base.MockitoException class SpyTest { @@ -34,6 +36,12 @@ class SpyTest { private val openClassInstance: MyClass = MyClass() private val closedClassInstance: ClosedClass = ClosedClass() + @After + fun a() { + Mockito.validateMockitoUsage() + } + + @Test fun spyInterfaceInstance() { /* When */ -- cgit v1.2.3 From 8157be64ce796d42d90f7c51635cfe7244108928 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 22:02:54 +0100 Subject: Support Boolean --- .../main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt | 2 ++ mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index f2abb61..155d0ad 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -66,6 +66,7 @@ private fun KClass<*>.isEnum() = java.isEnum private fun KClass<*>.isArray() = java.isArray private fun KClass<*>.isPrimitive() = java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf( + "Boolean", "Byte", "Short", "Int", @@ -78,6 +79,7 @@ private fun KClass<*>.isPrimitive() = @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") private fun KClass.toDefaultPrimitiveValue(): T { return when (simpleName) { + "Boolean" -> true "Byte" -> 0.toByte() "Short" -> 0.toShort() "Int" -> 0 diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index d2ea568..ca49417 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -83,6 +83,15 @@ class CreateInstanceTest { expect(result).toBeIn(-0.000001f..0.000001f) } + @Test + fun boolean() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(true) + } + @Test fun string() { /* When */ -- cgit v1.2.3 From 1d9a5889b2439fd55e3d239d8a93daf90ce475aa Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 24 Jan 2016 22:25:48 +0100 Subject: Use smallest constructor --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 155d0ad..58c234a 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -54,7 +54,7 @@ fun createInstance(kClass: KClass): T { kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() kClass.isEnum() -> kClass.java.enumConstants.first() kClass.isArray() -> kClass.toArrayInstance() - else -> kClass.constructors.first().newInstance() + else -> kClass.constructors.sortedBy { it.parameters.size }.first().newInstance() } } -- cgit v1.2.3 From 8b93c665a3c2bfbca13f0ec694140147e61d3240 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 4 Feb 2016 19:39:08 +0100 Subject: Update Kotlin to rc-1036 --- mockito-kotlin/build.gradle | 8 ++++---- .../main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 1b28258..fab1042 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.0-beta-4589" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.0-rc-1036" } } @@ -16,13 +16,13 @@ repositories { } dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.0-beta-4589" - compile "org.jetbrains.kotlin:kotlin-reflect:1.0.0-beta-4589" + compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.0-rc-1036" + compile "org.jetbrains.kotlin:kotlin-reflect:1.0.0-rc-1036" compile "org.mockito:mockito-core:2.0.39-beta" /* Tests */ testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:0.3.0" + testCompile "com.nhaarman:expect.kt:0.4.0" } publishing { diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 58c234a..3815da8 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -76,7 +76,7 @@ private fun KClass<*>.isPrimitive() = "String" ) -@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") +@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") private fun KClass.toDefaultPrimitiveValue(): T { return when (simpleName) { "Boolean" -> true @@ -91,7 +91,7 @@ private fun KClass.toDefaultPrimitiveValue(): T { } as T } -@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY") +@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") private fun KClass.toArrayInstance(): T { return when (simpleName) { "ByteArray" -> byteArrayOf() @@ -106,7 +106,7 @@ private fun KClass.toArrayInstance(): T { private fun KFunction.newInstance(): T { isAccessible = true - return callBy(parameters.toMap { + return callBy(parameters.associate { it to it.type.createNullableInstance() }) } @@ -130,7 +130,7 @@ private fun KType.createNullableInstance(): T? { */ @Suppress("UNCHECKED_CAST") private fun Class.uncheckedMock(): T { - val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl<*> + val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl val creationSettings = impl.confirm(this) - return MockUtil().createMock(creationSettings) as T + return MockUtil().createMock(creationSettings) } -- cgit v1.2.3 From 40bf7c65bb04d5f7ebf45fdcf8f7023ebb928273 Mon Sep 17 00:00:00 2001 From: Vincent Dubedout Date: Mon, 15 Feb 2016 14:33:49 -0500 Subject: changed kotlin version to 1.0.0 --- mockito-kotlin/build.gradle | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index fab1042..b26837e 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,12 +1,14 @@ apply plugin: 'kotlin' buildscript { + ext.kotlin_version = '1.0.0' + repositories { mavenCentral() } dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.0-rc-1036" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -16,8 +18,8 @@ repositories { } dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.0-rc-1036" - compile "org.jetbrains.kotlin:kotlin-reflect:1.0.0-rc-1036" + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "org.mockito:mockito-core:2.0.39-beta" /* Tests */ -- cgit v1.2.3 From 76be5d0a02865e3f8a1c018351f999b725ce7db1 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Wed, 17 Feb 2016 00:58:30 +0200 Subject: add more missing Mockito methods, especially to be used with spies --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 3d09323..f0643db 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -30,6 +30,7 @@ import org.mockito.verification.VerificationMode import kotlin.reflect.KClass inline fun mock() = Mockito.mock(T::class.java) +inline fun mock(defaultAnswer: Answer) = Mockito.mock(T::class.java, defaultAnswer) fun spy(value: T) = Mockito.spy(value) fun whenever(methodCall: T) = Mockito.`when`(methodCall) @@ -40,6 +41,17 @@ fun reset(mock: T) = Mockito.reset(mock) fun inOrder(vararg value: Any) = Mockito.inOrder(*value) fun never() = Mockito.never() +fun times(numInvocations: Int) = Mockito.times(numInvocations) +fun atLeast(numInvocations: Int) = Mockito.atLeast(numInvocations) +fun atLeastOnce() = Mockito.atLeastOnce() + +fun doReturn(value: Any) = Mockito.doReturn(value) +fun doThrow(throwable: Throwable) = Mockito.doThrow(throwable) +fun doAnswer(answer: Answer) = Mockito.doAnswer(answer) +fun doCallRealMethod() = Mockito.doCallRealMethod() +fun doNothing() = Mockito.doNothing() + +fun Stubber.whenever(mock: T) = `when`(mock) inline fun eq(value: T) = Mockito.eq(value) ?: createInstance() inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() -- cgit v1.2.3 From 334d4716d018b1dcae64f6a7feaae25aaa1ad86e Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Wed, 17 Feb 2016 01:05:25 +0200 Subject: add missing imports --- mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index f0643db..144d5a0 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -26,6 +26,8 @@ package com.nhaarman.mockito_kotlin import org.mockito.Mockito +import org.mockito.stubbing.Answer +import org.mockito.stubbing.Stubber import org.mockito.verification.VerificationMode import kotlin.reflect.KClass -- cgit v1.2.3 From 0efd093b42035b381e8c5b75e7204dd19f87e5e5 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 18 Feb 2016 13:37:27 +0100 Subject: Added PR template --- .github/PULL_REQUEST_TEMPLATE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..fa6cbc3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,5 @@ +Thank you for submitting a pull request! But first: + + - [ ] Can you back your code up with tests? + - [ ] Keep your commits clean: [squash your commits if necessary](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History). + - [ ] Make sure you're targeting the `dev` branch with the PR. -- cgit v1.2.3 From f6f142ade26f7586028ef8a82a2d1f7b1d7b14b7 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Fri, 19 Feb 2016 13:20:51 +0200 Subject: add spy stubbing tests --- mockito-kotlin/src/test/kotlin/SpyTest.kt | 33 ++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/test/kotlin/SpyTest.kt b/mockito-kotlin/src/test/kotlin/SpyTest.kt index 860abf9..e09ee25 100644 --- a/mockito-kotlin/src/test/kotlin/SpyTest.kt +++ b/mockito-kotlin/src/test/kotlin/SpyTest.kt @@ -24,11 +24,12 @@ */ import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.spy +import com.nhaarman.mockito_kotlin.* import org.junit.After import org.junit.Test import org.mockito.Mockito import org.mockito.exceptions.base.MockitoException +import java.util.* class SpyTest { @@ -66,6 +67,36 @@ class SpyTest { spy(closedClassInstance) } + @Test + fun doReturnWithSpy() { + val date = spy(Date()) + doReturn(123L).whenever(date).time + expect(date.time).toBe(123L) + } + + @Test + fun doNothingWithSpy() { + val date = spy(Date(0)) + doNothing().whenever(date).time = 5L + date.time = 5L; + expect(date.time).toBe(0L) + } + + @Test(expected = IllegalArgumentException::class) + fun doThrowWithSpy() { + val date = spy(Date(0)) + doThrow(IllegalArgumentException()).whenever(date).time + date.time + } + + @Test + fun doCallRealMethodWithSpy() { + val date = spy(Date(0)) + doReturn(123L).whenever(date).time + doCallRealMethod().whenever(date).time + expect(date.time).toBe(0L) + } + private interface MyInterface private open class MyClass : MyInterface private class ClosedClass -- cgit v1.2.3 From 1262c198418fb07d1cd5713104f7c756885b7b25 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Fri, 19 Feb 2016 13:25:42 +0200 Subject: add deep stubs test --- mockito-kotlin/src/test/kotlin/MockTest.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mockito-kotlin/src/test/kotlin/MockTest.kt b/mockito-kotlin/src/test/kotlin/MockTest.kt index 0ba7285..e46f3db 100644 --- a/mockito-kotlin/src/test/kotlin/MockTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockTest.kt @@ -25,8 +25,11 @@ import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.whenever import org.junit.Test +import org.mockito.Mockito.RETURNS_DEEP_STUBS import org.mockito.exceptions.base.MockitoException +import java.util.* class MockTest { @@ -82,6 +85,13 @@ class MockTest { mock() } + @Test + fun deepStubs() { + val cal: Calendar = mock(RETURNS_DEEP_STUBS) + whenever(cal.time.time).thenReturn(123L) + expect(cal.time.time).toBe(123L) + } + private interface MyInterface private open class MyClass private class ClosedClass -- cgit v1.2.3 From 66e3be5b74d7ddf3d58f0142de3aa7bd26f955d5 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Fri, 19 Feb 2016 13:43:48 +0200 Subject: add simplified ArgumentCaptor support --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 4 ++++ mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 144d5a0..4d8a7d4 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -25,6 +25,7 @@ package com.nhaarman.mockito_kotlin +import org.mockito.ArgumentCaptor import org.mockito.Mockito import org.mockito.stubbing.Answer import org.mockito.stubbing.Stubber @@ -55,6 +56,9 @@ fun doNothing() = Mockito.doNothing() fun Stubber.whenever(mock: T) = `when`(mock) +inline fun argumentCaptor() = ArgumentCaptor.forClass(T::class.java) +inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() + inline fun eq(value: T) = Mockito.eq(value) ?: createInstance() inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() inline fun any() = Mockito.any(T::class.java) ?: createInstance() diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt new file mode 100644 index 0000000..8f4afc2 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt @@ -0,0 +1,20 @@ +import com.nhaarman.mockito_kotlin.argumentCaptor +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.verify +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.capture +import org.junit.Test +import java.util.* + +class ArgumentCaptorTest { + @Test + fun captor() { + val date: Date = mock() + val time = argumentCaptor() + + date.time = 5L + + verify(date).time = capture(time) + expect(time.value).toBe(5L) + } +} \ No newline at end of file -- cgit v1.2.3 From 9238c4cd2de64ad385c4a26be29047c05e1e0bc4 Mon Sep 17 00:00:00 2001 From: "Anton Keks, Dmitri Ess" Date: Tue, 8 Mar 2016 16:51:00 +0200 Subject: add simpler capture() method with lambda --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 4 ++++ mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 4d8a7d4..549ad2f 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -58,6 +58,10 @@ fun Stubber.whenever(mock: T) = `when`(mock) inline fun argumentCaptor() = ArgumentCaptor.forClass(T::class.java) inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() +inline fun capture(noinline consumer: (T) -> Unit): T { + var times = 0 + return argThat { if (++times == 1) consumer.invoke(this); true } +} inline fun eq(value: T) = Mockito.eq(value) ?: createInstance() inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt index 8f4afc2..9773e76 100644 --- a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt +++ b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt @@ -8,7 +8,7 @@ import java.util.* class ArgumentCaptorTest { @Test - fun captor() { + fun explicitCaptor() { val date: Date = mock() val time = argumentCaptor() @@ -17,4 +17,14 @@ class ArgumentCaptorTest { verify(date).time = capture(time) expect(time.value).toBe(5L) } + + @Test + fun implicitCaptor() { + val date: Date = mock() + date.time = 5L + + verify(date).time = capture { + expect(it).toBe(5L) + } + } } \ No newline at end of file -- cgit v1.2.3 From 5105493f244ec811163dc0f1b94177e19adb9619 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 10 Mar 2016 13:11:57 +0100 Subject: Include more static Mockito methods --- gradle/wrapper/gradle-wrapper.properties | 2 +- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 31 +++ .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 2 +- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 85 ++++--- .../kotlin/com/nhaarman/mockito_kotlin/Stubber.kt | 30 +++ .../src/test/kotlin/ArgumentCaptorTest.kt | 1 + mockito-kotlin/src/test/kotlin/Classes.kt | 54 +++++ .../src/test/kotlin/CreateInstanceTest.kt | 4 +- mockito-kotlin/src/test/kotlin/EqTest.kt | 2 +- mockito-kotlin/src/test/kotlin/Fake.kt | 29 --- mockito-kotlin/src/test/kotlin/MatcherTest.kt | 54 ----- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 257 +++++++++++++++++++++ 12 files changed, 436 insertions(+), 115 deletions(-) create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt create mode 100644 mockito-kotlin/src/test/kotlin/Classes.kt delete mode 100644 mockito-kotlin/src/test/kotlin/Fake.kt delete mode 100644 mockito-kotlin/src/test/kotlin/MatcherTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/MockitoTest.kt diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 909374a..8ccb210 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt new file mode 100644 index 0000000..cffb582 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt @@ -0,0 +1,31 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockito_kotlin + +import org.mockito.ArgumentCaptor + +inline fun argumentCaptor() = ArgumentCaptor.forClass(T::class.java) +inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 3815da8..4d9558c 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -100,7 +100,7 @@ private fun KClass.toArrayInstance(): T { "LongArray" -> longArrayOf() "DoubleArray" -> doubleArrayOf() "FloatArray" -> floatArrayOf() - else -> throw UnsupportedOperationException("Cannot create a generic array for $simpleName. Use createArrayInstance() instead.") + else -> throw UnsupportedOperationException("Cannot create a generic array for $simpleName. Use createArrayInstance() or anyArray() instead.") } as T } diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 4d8a7d4..a12b8f3 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -25,47 +25,78 @@ package com.nhaarman.mockito_kotlin -import org.mockito.ArgumentCaptor +import org.mockito.MockSettings import org.mockito.Mockito +import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Answer -import org.mockito.stubbing.Stubber import org.mockito.verification.VerificationMode import kotlin.reflect.KClass -inline fun mock() = Mockito.mock(T::class.java) -inline fun mock(defaultAnswer: Answer) = Mockito.mock(T::class.java, defaultAnswer) -fun spy(value: T) = Mockito.spy(value) +fun after(millis: Long) = Mockito.after(millis) -fun whenever(methodCall: T) = Mockito.`when`(methodCall) -fun verify(mock: T) = Mockito.verify(mock) -fun verify(mock: T, mode: VerificationMode) = Mockito.verify(mock, mode) -fun verifyNoMoreInteractions(mock: T) = Mockito.verifyNoMoreInteractions(mock) -fun reset(mock: T) = Mockito.reset(mock) +inline fun any() = Mockito.any(T::class.java) ?: createInstance() +inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() +inline fun anyCollection(): Collection = Mockito.anyCollectionOf(T::class.java) +inline fun anyList(): List = Mockito.anyListOf(T::class.java) +inline fun anySet(): Set = Mockito.anySetOf(T::class.java) +inline fun anyMap(): Map = Mockito.anyMapOf(K::class.java, V::class.java) +inline fun anyVararg() = Mockito.anyVararg() ?: createInstance() + +inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) -fun inOrder(vararg value: Any) = Mockito.inOrder(*value) -fun never() = Mockito.never() -fun times(numInvocations: Int) = Mockito.times(numInvocations) fun atLeast(numInvocations: Int) = Mockito.atLeast(numInvocations) fun atLeastOnce() = Mockito.atLeastOnce() +fun atMost(maxNumberOfInvocations: Int) = Mockito.atMost(maxNumberOfInvocations) +fun calls(wantedNumberOfInvocations: Int) = Mockito.calls(wantedNumberOfInvocations) -fun doReturn(value: Any) = Mockito.doReturn(value) -fun doThrow(throwable: Throwable) = Mockito.doThrow(throwable) -fun doAnswer(answer: Answer) = Mockito.doAnswer(answer) -fun doCallRealMethod() = Mockito.doCallRealMethod() -fun doNothing() = Mockito.doNothing() +fun clearInvocations(vararg mocks: T) = Mockito.clearInvocations(*mocks) +fun description(description: String) = Mockito.description(description) -fun Stubber.whenever(mock: T) = `when`(mock) +fun doAnswer(answer: (InvocationOnMock) -> T?) = Mockito.doAnswer { answer(it) } -inline fun argumentCaptor() = ArgumentCaptor.forClass(T::class.java) -inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() +fun doCallRealMethod() = Mockito.doCallRealMethod() +fun doNothing() = Mockito.doNothing() +fun doReturn(value: Any) = Mockito.doReturn(value) +fun doReturn(toBeReturned: Any, vararg toBeReturnedNext: Any) = Mockito.doReturn(toBeReturned, *toBeReturnedNext) +fun doThrow(toBeThrown: KClass) = Mockito.doThrow(toBeThrown.java) +fun doThrow(vararg toBeThrown: Throwable) = Mockito.doThrow(*toBeThrown) inline fun eq(value: T) = Mockito.eq(value) ?: createInstance() -inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() -inline fun any() = Mockito.any(T::class.java) ?: createInstance() +fun ignoreStubs(vararg mocks: Any) = Mockito.ignoreStubs(*mocks) +fun inOrder(vararg mocks: Any) = Mockito.inOrder(*mocks) + +inline fun isA() = Mockito.isA(T::class.java) +inline fun isNotNull() = Mockito.isNotNull(T::class.java) inline fun isNull(): T? = Mockito.isNull(T::class.java) -inline fun argThat(noinline predicate: T.() -> Boolean) = argThat(T::class, predicate) +inline fun mock() = Mockito.mock(T::class.java) +inline fun mock(defaultAnswer: Answer) = Mockito.mock(T::class.java, defaultAnswer) +inline fun mock(s: MockSettings) = Mockito.mock(T::class.java, s) +inline fun mock(s: String) = Mockito.mock(T::class.java, s) + +fun mockingDetails(toInspect: Any) = Mockito.mockingDetails(toInspect) +fun never() = Mockito.never() +inline fun notNull() = Mockito.notNull(T::class.java) +fun only() = Mockito.only() +fun refEq(value: T, vararg excludeFields: String) = Mockito.refEq(value, *excludeFields) + +fun reset() = Mockito.reset() +fun reset(vararg mocks: T) = Mockito.reset(*mocks) -@Suppress("UNCHECKED_CAST") -fun argThat(kClass: KClass, predicate: T.() -> Boolean) - = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(kClass) +fun same(value: T) = Mockito.same(value) + +inline fun spy() = Mockito.spy(T::class.java) +fun spy(value: T) = Mockito.spy(value) + +fun stub(methodCall: T) = Mockito.stub(methodCall) +fun timeout(millis: Long) = Mockito.timeout(millis) +fun times(numInvocations: Int) = Mockito.times(numInvocations) +fun validateMockitoUsage() = Mockito.validateMockitoUsage() + +fun verify(mock: T) = Mockito.verify(mock) +fun verify(mock: T, mode: VerificationMode) = Mockito.verify(mock, mode) +fun verifyNoMoreInteractions(vararg mocks: T) = Mockito.verifyNoMoreInteractions(*mocks) +fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(*mocks) + +fun whenever(methodCall: T) = Mockito.`when`(methodCall) +fun withSettings() = Mockito.withSettings() \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt new file mode 100644 index 0000000..cfb0bd5 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt @@ -0,0 +1,30 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockito_kotlin + +import org.mockito.stubbing.Stubber + +fun Stubber.whenever(mock: T) = `when`(mock) diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt index 8f4afc2..8b5ec92 100644 --- a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt +++ b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt @@ -7,6 +7,7 @@ import org.junit.Test import java.util.* class ArgumentCaptorTest { + @Test fun captor() { val date: Date = mock() diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt new file mode 100644 index 0000000..f0ff2df --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -0,0 +1,54 @@ +/* +* The MIT License +* +* Copyright (c) 2016 Niek Haarman +* Copyright (c) 2007 Mockito contributors +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +open class Open { + open fun go(vararg arg: Any?) { + } + + open fun modifiesContents(a: IntArray) { + for (i in 0..a.size - 1) { + a[i] = a[i] + 1 + } + } + + open fun stringResult() = "Default" +} + +class Closed + +interface Methods { + + fun intArray(i: IntArray) + fun closed(c: Closed) + fun closedArray(a: Array) + fun closedCollection(c: Collection) + fun closedList(c: List) + fun closedStringMap(m: Map) + fun closedSet(s: Set) + fun string(s: String) + fun closedVararg(vararg c: Closed) + + fun stringResult(): String +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index ca49417..1bfcd91 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -158,7 +158,7 @@ class CreateInstanceTest { @Test(expected = UnsupportedOperationException::class) fun classArray_usingAny() { /* When */ - createInstance>() + createInstance>() } @Test @@ -371,7 +371,7 @@ class CreateInstanceTest { private class PrivateClass private constructor(val data: String) class ClosedClass - class ClosedParameterizedClass(val fake: Fake) + class ClosedParameterizedClass(val open: Open) class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) class SingleParameterClass(val first: Byte) diff --git a/mockito-kotlin/src/test/kotlin/EqTest.kt b/mockito-kotlin/src/test/kotlin/EqTest.kt index dd10766..3e4294d 100644 --- a/mockito-kotlin/src/test/kotlin/EqTest.kt +++ b/mockito-kotlin/src/test/kotlin/EqTest.kt @@ -37,7 +37,7 @@ class EqTest { private val openClassInstance: MyClass = MyClass() private val closedClassInstance: ClosedClass = ClosedClass() - private lateinit var doAnswer: Fake + private lateinit var doAnswer: Open @Before fun setup() { diff --git a/mockito-kotlin/src/test/kotlin/Fake.kt b/mockito-kotlin/src/test/kotlin/Fake.kt deleted file mode 100644 index 7aa9743..0000000 --- a/mockito-kotlin/src/test/kotlin/Fake.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* -* The MIT License -* -* Copyright (c) 2016 Niek Haarman -* Copyright (c) 2007 Mockito contributors -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -open class Fake { - open fun go(arg: Any?) { - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/MatcherTest.kt b/mockito-kotlin/src/test/kotlin/MatcherTest.kt deleted file mode 100644 index 770c67f..0000000 --- a/mockito-kotlin/src/test/kotlin/MatcherTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.mockito_kotlin.argThat -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.verify -import org.junit.Test - -class MatcherTest { - - @Test - fun argThat() { - /* Given */ - val testClass: TestClass = mock() - - /* When */ - testClass.go(listOf("test")) - - /* Then */ - verify(testClass).go( - argThat { - size == 1 - get(0) == "test" - } - ) - } - - interface TestClass { - - fun go(v: List) - } -} diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt new file mode 100644 index 0000000..394594b --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -0,0 +1,257 @@ +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockito_kotlin.* +import org.junit.Test +import org.mockito.exceptions.base.MockitoAssertionError + +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +class MockitoTest { + + @Test + fun anyString() { + mock().apply { + string("") + verify(this).string(any()) + } + } + + @Test + fun anyClosedClass() { + mock().apply { + closed(Closed()) + verify(this).closed(any()) + } + } + + @Test + fun anyIntArray() { + mock().apply { + intArray(intArrayOf()) + verify(this).intArray(any()) + } + } + + @Test + fun anyClassArray() { + mock().apply { + closedArray(arrayOf(Closed())) + verify(this).closedArray(anyArray()) + } + } + + @Test + fun anyCollectionOfClosed() { + mock().apply { + closedCollection(listOf()) + verify(this).closedCollection(any()) + verify(this).closedCollection(anyCollection()) + } + } + + @Test + fun anyListOfClosed() { + mock().apply { + closedList(listOf()) + verify(this).closedList(any()) + verify(this).closedList(anyList()) + } + } + + @Test + fun anyClosedStringMap() { + mock().apply { + closedStringMap(mapOf()) + verify(this).closedStringMap(any()) + verify(this).closedStringMap(anyMap()) + } + } + + @Test + fun anyClosedSet() { + mock().apply { + closedSet(setOf()) + verify(this).closedSet(any()) + verify(this).closedSet(anySet()) + } + } + + @Test + fun anyStringVararg() { + mock().apply { + closedVararg(Closed(), Closed()) + verify(this).closedVararg(anyVararg()) + } + } + + @Test + fun listArgThat() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList(argThat { + size == 2 + }) + } + } + + @Test + fun atLeastXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atLeast(2)).string(any()) + } + } + + @Test + fun testAtLeastOnce() { + mock().apply { + string("") + string("") + + verify(this, atLeastOnce()).string(any()) + } + } + + @Test + fun atMostXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atMost(2)).string(any()) + } + } + + @Test + fun testCalls() { + mock().apply { + string("") + string("") + + inOrder(this).verify(this, calls(2)).string(any()) + } + } + + @Test + fun testClearInvocations() { + val mock = mock().apply { + string("") + } + + clearInvocations(mock) + + verify(mock, never()).string(any()) + } + + @Test + fun testDescription() { + try { + mock().apply { + verify(this, description("Test")).string(any()) + } + throw AssertionError("Verify should throw Exception.") + } catch (e: MockitoAssertionError) { + expect(e.message).toContain("Test") + } + } + + @Test + fun testDoAnswer() { + val mock = mock() + + doAnswer { "Test" } + .whenever(mock) + .stringResult() + + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun testDoCallRealMethod() { + val mock = mock() + + doReturn("Test").whenever(mock).stringResult() + doCallRealMethod().whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("Default") + } + + @Test + fun testDoNothing() { + val spy = spy(Open()) + val array = intArrayOf(3) + + doNothing().whenever(spy).modifiesContents(array) + spy.modifiesContents(array) + + expect(array[0]).toBe(3) + } + + @Test + fun testDoReturnValue() { + val mock = mock() + + doReturn("test").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + } + + @Test + fun testDoReturnValues() { + val mock = mock() + + doReturn("test", "test2").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + expect(mock.stringResult()).toBe("test2") + } + + @Test + fun testDoThrowClass() { + val mock = mock() + + doThrow(IllegalStateException::class).whenever(mock).go() + + try { + mock.go() + throw AssertionError("Call should have thrown.") + } catch(e: IllegalStateException) { + } + } + + @Test + fun testDoThrow() { + val mock = mock() + + doThrow(IllegalStateException("test")).whenever(mock).go() + + expectErrorWithMessage("test").on { + mock.go() + } + } +} -- cgit v1.2.3 From ea0263db4d0838cbd92c857c073e0172a87ae644 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 15 Mar 2016 00:03:44 +0100 Subject: Avoid constructors with an array as a parameter. The UUID class has a single-argument constructor which expects an array with some specific contents. This commit tries to avoid these type of constructors, since it may be a common case. Instead, it tries to find a constructor without an array parameter, or otherwise falls back. Fixes issue #17. --- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 22 +++++++++++++++++++++- .../src/test/kotlin/CreateInstanceTest.kt | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 4d9558c..8910770 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -54,10 +54,30 @@ fun createInstance(kClass: KClass): T { kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() kClass.isEnum() -> kClass.java.enumConstants.first() kClass.isArray() -> kClass.toArrayInstance() - else -> kClass.constructors.sortedBy { it.parameters.size }.first().newInstance() + else -> kClass.easiestConstructor().newInstance() } } +/** + * Tries to find the easiest constructor which it can instantiate. + */ +private fun KClass.easiestConstructor(): KFunction { + return constructors.firstOrDefault( + { + it.parameters.filter { + it.type.toString().toLowerCase().contains("array") + }.isEmpty() + }, + { + constructors.sortedBy { it.parameters.size }.first() + } + ) +} + +private fun Collection.firstOrDefault(predicate: (T) -> Boolean, default: () -> T): T { + return firstOrNull(predicate) ?: default() +} + @Suppress("SENSELESS_COMPARISON") private fun KClass<*>.hasObjectInstance() = objectInstance != null diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index 1bfcd91..b4ce358 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -26,6 +26,7 @@ import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.createInstance import org.junit.Test +import java.util.* class CreateInstanceTest { @@ -368,6 +369,21 @@ class CreateInstanceTest { expect(result).toNotBeNull() } + @Test + fun uuid() { + /** + * The UUID class has a single-argument constructor that expects an array with some specific contents. + * We avoid these types of constructors by calling another constructor, if available. + * In this case, UUID(Long, Long). + */ + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBeEqualTo(UUID(0, 0)) + } + private class PrivateClass private constructor(val data: String) class ClosedClass -- cgit v1.2.3 From ae4ab1708b1ce8028de094d02d29a2fe6fae879e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 27 Mar 2016 14:50:49 +0200 Subject: Account for Class when creating instances. --- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 8 ++++++++ mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 8910770..8a7cb30 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -37,6 +37,7 @@ import kotlin.reflect.KType import kotlin.reflect.defaultType import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaType +import kotlin.reflect.jvm.jvmName /** * A collection of functions that tries to create an instance of @@ -54,6 +55,7 @@ fun createInstance(kClass: KClass): T { kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() kClass.isEnum() -> kClass.java.enumConstants.first() kClass.isArray() -> kClass.toArrayInstance() + kClass.isClassObject() -> kClass.toClassObject() else -> kClass.easiestConstructor().newInstance() } } @@ -84,6 +86,7 @@ private fun KClass<*>.hasObjectInstance() = objectInstance != null private fun KClass<*>.isMockable() = !Modifier.isFinal(java.modifiers) private fun KClass<*>.isEnum() = java.isEnum private fun KClass<*>.isArray() = java.isArray +private fun KClass<*>.isClassObject() = jvmName.equals("java.lang.Class") private fun KClass<*>.isPrimitive() = java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf( "Boolean", @@ -124,6 +127,11 @@ private fun KClass.toArrayInstance(): T { } as T } +@Suppress("UNCHECKED_CAST") +private fun KClass.toClassObject(): T { + return Class.forName("java.lang.Object") as T +} + private fun KFunction.newInstance(): T { isAccessible = true return callBy(parameters.associate { diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index b4ce358..8b8979a 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -27,6 +27,7 @@ import com.nhaarman.expect.expect import com.nhaarman.mockito_kotlin.createInstance import org.junit.Test import java.util.* +import kotlin.reflect.KClass class CreateInstanceTest { @@ -369,6 +370,24 @@ class CreateInstanceTest { expect(result).toNotBeNull() } + @Test + fun classObject() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun kClassObject() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + @Test fun uuid() { /** -- cgit v1.2.3 From c8d9f689563eae6331ba21fa80d54f14eff159c0 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 27 Mar 2016 16:00:41 +0200 Subject: Unset the MockitoInterceptor for unchecked mocks. This allows the default functions to be called on these mocks during verification. Apparently, the MockitoInterceptor added by Mockito does some internal state checking. This is not necessary here. --- .../main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt | 5 ++++- mockito-kotlin/src/test/kotlin/Classes.kt | 5 ++++- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 9 +++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 8a7cb30..3bc508a 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -27,6 +27,7 @@ package com.nhaarman.mockito_kotlin import org.mockito.Answers import org.mockito.internal.creation.MockSettingsImpl +import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor import org.mockito.internal.util.MockUtil import java.lang.reflect.Modifier import java.lang.reflect.ParameterizedType @@ -160,5 +161,7 @@ private fun KType.createNullableInstance(): T? { private fun Class.uncheckedMock(): T { val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl val creationSettings = impl.confirm(this) - return MockUtil().createMock(creationSettings) + return MockUtil().createMock(creationSettings).apply { + (this as MockMethodInterceptor.MockAccess).mockitoInterceptor = null + } } diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index f0ff2df..d494872 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -49,6 +49,9 @@ interface Methods { fun closedSet(s: Set) fun string(s: String) fun closedVararg(vararg c: Closed) + fun throwableClass(t: ThrowableClass) fun stringResult(): String -} \ No newline at end of file +} + +class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 394594b..ef635b3 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -3,6 +3,7 @@ import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.mockito_kotlin.* import org.junit.Test import org.mockito.exceptions.base.MockitoAssertionError +import java.io.IOException /* * The MIT License @@ -107,6 +108,14 @@ class MockitoTest { } } + @Test + fun anyThrowableWithSingleThrowableConstructor() { + mock().apply { + throwableClass(ThrowableClass(IOException())) + verify(this).throwableClass(any()) + } + } + @Test fun listArgThat() { mock().apply { -- cgit v1.2.3 From df0c3f69d42ed1637995d18ca527ef9c81356fab Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 27 Mar 2016 16:19:41 +0200 Subject: Remove Travis-CI cache --- .travis.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index fce01cd..150dc86 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,14 +14,3 @@ install: script: - ./gradlew test - -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties.lock - - rm -f $HOME/.gradle/caches/2.10/plugin-resolution/cache.properties -cache: - directories: - - $HOME/.gradle/caches - - $HOME/.gradle/daemon - - $HOME/.gradle/native - - $HOME/.gradle/wrapper \ No newline at end of file -- cgit v1.2.3 From 1322b92cc6372b24a5b9fedf61c2d06922368ea5 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 17 Apr 2016 11:52:45 +0200 Subject: Update dependencies - Kotlin 1.0.0 -> 1.0.1-2 - Mockito 2.0.39-beta -> 2.0.47-beta - Expect.kt 0.4.0 -> 0.5.0 --- mockito-kotlin/build.gradle | 6 +++--- mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index b26837e..323651d 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'kotlin' buildscript { - ext.kotlin_version = '1.0.0' + ext.kotlin_version = '1.0.1-2' repositories { mavenCentral() @@ -20,11 +20,11 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.0.39-beta" + compile "org.mockito:mockito-core:2.0.47-beta" /* Tests */ testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:0.4.0" + testCompile "com.nhaarman:expect.kt:0.5.0" } publishing { diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index 8b8979a..84e321c 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -100,7 +100,7 @@ class CreateInstanceTest { val result = createInstance() /* Then */ - expect(result).toBeEqualTo("") + expect(result).toBe("") } @Test @@ -400,7 +400,7 @@ class CreateInstanceTest { val result = createInstance() /* Then */ - expect(result).toBeEqualTo(UUID(0, 0)) + expect(result).toBe(UUID(0, 0)) } private class PrivateClass private constructor(val data: String) -- cgit v1.2.3 From abfc0833ae9b737d10bf3ec929977e911ed2b3f9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 14 May 2016 16:11:07 +0200 Subject: Update dependencies - Kotlin: 1.0.1-2 -> 1.0.2 - Mockito: 2.0.48-beta -> 2.0.52-beta - Expect.kt: 0.5.0 -> 0.5.1 --- mockito-kotlin/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 323651d..2a8d75d 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'kotlin' buildscript { - ext.kotlin_version = '1.0.1-2' + ext.kotlin_version = '1.0.2' repositories { mavenCentral() @@ -20,11 +20,11 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.0.47-beta" + compile "org.mockito:mockito-core:2.0.52-beta" /* Tests */ testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:0.5.0" + testCompile "com.nhaarman:expect.kt:0.5.1" } publishing { -- cgit v1.2.3 From cddcf7f0cacbb5ec5424e8abcdbd232a30d65002 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 19 Mar 2016 10:28:49 +0100 Subject: Introduce instance creators. These are functions `() -> T` that are invoked when an instance of `T` is needed, instead of manually trying to figure out which constructor to use. Fixes #20. --- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 40 +++++++++---- .../com/nhaarman/mockito_kotlin/MockitoKotlin.kt | 69 ++++++++++++++++++++++ .../mockito_kotlin/MockitoKotlinException.kt | 28 +++++++++ .../src/test/kotlin/CreateInstanceTest.kt | 31 ++++++++++ .../src/test/kotlin/MockitoKotlinTest.kt | 59 ++++++++++++++++++ 5 files changed, 215 insertions(+), 12 deletions(-) create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt create mode 100644 mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 3bc508a..034d3e4 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -29,6 +29,7 @@ import org.mockito.Answers import org.mockito.internal.creation.MockSettingsImpl import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor import org.mockito.internal.util.MockUtil +import java.lang.reflect.InvocationTargetException import java.lang.reflect.Modifier import java.lang.reflect.ParameterizedType import java.lang.reflect.Type @@ -49,16 +50,18 @@ inline fun createArrayInstance() = arrayOf() inline fun createInstance() = createInstance(T::class) +@Suppress("UNCHECKED_CAST") fun createInstance(kClass: KClass): T { - return when { - kClass.hasObjectInstance() -> kClass.objectInstance!! - kClass.isMockable() -> kClass.java.uncheckedMock() - kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() - kClass.isEnum() -> kClass.java.enumConstants.first() - kClass.isArray() -> kClass.toArrayInstance() + return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?: + when { + kClass.hasObjectInstance() -> kClass.objectInstance!! + kClass.isMockable() -> kClass.java.uncheckedMock() + kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() + kClass.isEnum() -> kClass.java.enumConstants.first() + kClass.isArray() -> kClass.toArrayInstance() kClass.isClassObject() -> kClass.toClassObject() - else -> kClass.easiestConstructor().newInstance() - } + else -> kClass.easiestConstructor().newInstance() + } } /** @@ -134,10 +137,23 @@ private fun KClass.toClassObject(): T { } private fun KFunction.newInstance(): T { - isAccessible = true - return callBy(parameters.associate { - it to it.type.createNullableInstance() - }) + try { + isAccessible = true + return callBy(parameters.associate { + it to it.type.createNullableInstance() + }) + } catch(e: InvocationTargetException) { + throw MockitoKotlinException( + """ + + Could not create an instance of class ${this.returnType}, because of an error with the following message: + + "${e.cause?.message}" + + Try registering an instance creator yourself, using MockitoKotlin.registerInstanceCreator<${this.returnType}> {...}.""", + e.cause + ) + } } @Suppress("UNCHECKED_CAST") diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt new file mode 100644 index 0000000..e6e2a2f --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt @@ -0,0 +1,69 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockito_kotlin + +import java.util.* +import kotlin.reflect.KClass + +class MockitoKotlin { + + companion object { + + /** + * Maps KClasses to functions that can create an instance of that KClass. + */ + private val creators: MutableMap, () -> Any> = HashMap() + + /** + * Registers a function to be called when an instance of T is necessary. + */ + inline fun registerInstanceCreator(noinline creator: () -> T) = registerInstanceCreator(T::class, creator) + + /** + * Registers a function to be called when an instance of T is necessary. + */ + fun registerInstanceCreator(kClass: KClass, creator: () -> T) = creators.put(kClass, creator) + + /** + * Unregisters an instance creator. + */ + inline fun unregisterInstanceCreator() = unregisterInstanceCreator(T::class) + + /** + * Unregisters an instance creator. + */ + fun unregisterInstanceCreator(kClass: KClass) = creators.remove(kClass) + + /** + * Clears al instance creators. + */ + fun resetInstanceCreators() = creators.clear() + + internal fun instanceCreator(kClass: KClass): (() -> Any)? { + return creators[kClass] + } + } +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt new file mode 100644 index 0000000..f183802 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt @@ -0,0 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockito_kotlin + +class MockitoKotlinException(message: String?, cause: Throwable?) : RuntimeException(message, cause) diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index 84e321c..75bddb1 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -24,6 +24,8 @@ */ import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockito_kotlin.MockitoKotlin import com.nhaarman.mockito_kotlin.createInstance import org.junit.Test import java.util.* @@ -403,6 +405,25 @@ class CreateInstanceTest { expect(result).toBe(UUID(0, 0)) } + @Test + fun registeredInstanceCreator() { + /* Given */ + MockitoKotlin.registerInstanceCreator { ForbiddenConstructor(2) } + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun failedConstructor_throwsDescriptiveError() { + expectErrorWithMessage("Could not create an instance of class") on { + createInstance() + } + } + private class PrivateClass private constructor(val data: String) class ClosedClass @@ -428,5 +449,15 @@ class CreateInstanceTest { class ParameterizedClass(val t: T) class NullableParameterClass(val s: String?) + class ForbiddenConstructor { + + constructor() { + throw AssertionError("Forbidden.") + } + + constructor(value: Int) { + } + } + enum class MyEnum { VALUE, ANOTHER_VALUE } } diff --git a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt new file mode 100644 index 0000000..7f80565 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt @@ -0,0 +1,59 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.MockitoKotlin +import com.nhaarman.mockito_kotlin.createInstance +import org.junit.Test + +class MockitoKotlinTest { + + @Test + fun register() { + /* Given */ + val closed = Closed() + MockitoKotlin.registerInstanceCreator { closed } + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(closed) + } + + @Test + fun unregister() { + /* Given */ + val closed = Closed() + MockitoKotlin.registerInstanceCreator { closed } + MockitoKotlin.unregisterInstanceCreator() + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeReferentially(closed) + } +} -- cgit v1.2.3 From 17dadf9514a2576ffcca4df61f4d074500af1f21 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 19 Mar 2016 10:38:07 +0100 Subject: Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 2948f66..0b4fa53 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,20 @@ For generic arrays, use the `anyArray()` method: verify(myClass).setItems(anyArray()) ``` +## Custom instance creators + +There are some cases where Mockito-Kotlin cannot create an instance of a class. +This can for instance be when a constructor has some specific preconditions +for its parameters. +You can _register_ `instance creators` to overcome this: + +```kotlin +MockitoKotlin.registerInstanceCreator { MyClass(5) } +``` + +Whenever MockitoKotlin needs to create an instance of `MyClass`, this function is called, +giving you ultimate control over how these instances are created. + ### Argument Matchers Using higher-order functions, you can write very clear expectations about expected values. -- cgit v1.2.3 From f765a318f996801658f1b989f3ade5366bb27eec Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 1 Jun 2016 15:38:44 +0200 Subject: Use instance creators only from single test file. This ensures that ordering of tests does not influence the initialization of the instance creators, assuming this is done in the setup phase of the test. --- README.md | 3 +++ .../com/nhaarman/mockito_kotlin/MockitoKotlin.kt | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b4fa53..b046e82 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,9 @@ MockitoKotlin.registerInstanceCreator { MyClass(5) } Whenever MockitoKotlin needs to create an instance of `MyClass`, this function is called, giving you ultimate control over how these instances are created. +These instance creators work on a per-file basis: for each of your test files +you will need to register them again. + ### Argument Matchers Using higher-order functions, you can write very clear expectations about expected values. diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt index e6e2a2f..2158d7a 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt @@ -35,7 +35,7 @@ class MockitoKotlin { /** * Maps KClasses to functions that can create an instance of that KClass. */ - private val creators: MutableMap, () -> Any> = HashMap() + private val creators: MutableMap, MutableList Any>>> = HashMap() /** * Registers a function to be called when an instance of T is necessary. @@ -45,7 +45,12 @@ class MockitoKotlin { /** * Registers a function to be called when an instance of T is necessary. */ - fun registerInstanceCreator(kClass: KClass, creator: () -> T) = creators.put(kClass, creator) + fun registerInstanceCreator(kClass: KClass, creator: () -> T) { + val element = Error().stackTrace[1] + + creators.getOrPut(kClass) { ArrayList Any>>() } + .add(element.toFileIdentifier() to creator) + } /** * Unregisters an instance creator. @@ -63,7 +68,16 @@ class MockitoKotlin { fun resetInstanceCreators() = creators.clear() internal fun instanceCreator(kClass: KClass): (() -> Any)? { + val stacktrace = Error().stackTrace.filterNot { + it.className.contains("com.nhaarman.mockito_kotlin") + }[0] + return creators[kClass] + ?.filter { it.first == stacktrace.toFileIdentifier() } + ?.firstOrNull() + ?.second } + + private fun StackTraceElement.toFileIdentifier() = "$fileName$className" } } -- cgit v1.2.3 From c44c15ae1d680d961f703bcde76aa8e7089d855d Mon Sep 17 00:00:00 2001 From: Ivan Morgillo Date: Sun, 26 Jun 2016 17:06:52 +0200 Subject: Update Kotlin version --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 2a8d75d..946a9cb 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'kotlin' buildscript { - ext.kotlin_version = '1.0.2' + ext.kotlin_version = '1.0.2-1' repositories { mavenCentral() -- cgit v1.2.3 From 8e6ab1551180db9ce8e6a0022901401dfe2974c8 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 29 Jun 2016 16:21:29 +0200 Subject: Update gradle wrapper version --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8ccb210..554f6fe 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-all.zip -- cgit v1.2.3 From e1de1f64d2ad4d280a4ec7afe020fddab4128999 Mon Sep 17 00:00:00 2001 From: Micah Zoltu Date: Thu, 21 Jul 2016 15:43:18 +0000 Subject: Makes `mock` return non-null types. Since `Mockito.mock` is a Java function it returns a Kotlin platform type. By adding an explicit return type to the wrapper, the kotlin version of `mock` will now return a non-platform type. In this case, we know that `Mockito.mock` doesn't return null so we can safely make the wrapper return a non-null type. We add the `!!` to make it clear to the reader our intent is to strip the platform type at this point, and also make the Kotlin compiler add an explicit null-check "just in case" before returning from the kotlin `mock` method. --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index a12b8f3..dabccac 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -69,10 +69,10 @@ inline fun isA() = Mockito.isA(T::class.java) inline fun isNotNull() = Mockito.isNotNull(T::class.java) inline fun isNull(): T? = Mockito.isNull(T::class.java) -inline fun mock() = Mockito.mock(T::class.java) -inline fun mock(defaultAnswer: Answer) = Mockito.mock(T::class.java, defaultAnswer) -inline fun mock(s: MockSettings) = Mockito.mock(T::class.java, s) -inline fun mock(s: String) = Mockito.mock(T::class.java, s) +inline fun mock(): T = Mockito.mock(T::class.java)!! +inline fun mock(defaultAnswer: Answer): T = Mockito.mock(T::class.java, defaultAnswer)!! +inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! +inline fun mock(s: String): T = Mockito.mock(T::class.java, s)!! fun mockingDetails(toInspect: Any) = Mockito.mockingDetails(toInspect) fun never() = Mockito.never() @@ -99,4 +99,4 @@ fun verifyNoMoreInteractions(vararg mocks: T) = Mockito.verifyNoMoreInteract fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(*mocks) fun whenever(methodCall: T) = Mockito.`when`(methodCall) -fun withSettings() = Mockito.withSettings() \ No newline at end of file +fun withSettings() = Mockito.withSettings() -- cgit v1.2.3 From 25fb19c68b92321a9b658c259a4157ce1ceba25f Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 26 Jul 2016 21:08:51 +0200 Subject: Upgrade Kotlin version to 1.0.3. - Fixes #51 - Closes #44 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 946a9cb..6c6bdb1 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'kotlin' buildscript { - ext.kotlin_version = '1.0.2-1' + ext.kotlin_version = '1.0.3' repositories { mavenCentral() -- cgit v1.2.3 From c3e6182c327825249f721d003c0295caf57d55ad Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 26 Jul 2016 21:28:30 +0200 Subject: Specify explicit return types for Mockito calls. --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 71 ++++++++++++---------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index dabccac..11e5f81 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -25,11 +25,17 @@ package com.nhaarman.mockito_kotlin +import org.mockito.InOrder import org.mockito.MockSettings +import org.mockito.MockingDetails import org.mockito.Mockito import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Answer +import org.mockito.stubbing.DeprecatedOngoingStubbing +import org.mockito.stubbing.OngoingStubbing +import org.mockito.stubbing.Stubber import org.mockito.verification.VerificationMode +import org.mockito.verification.VerificationWithTimeout import kotlin.reflect.KClass fun after(millis: Long) = Mockito.after(millis) @@ -44,29 +50,29 @@ inline fun anyVararg() = Mockito.anyVararg() ?: createInsta inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) -fun atLeast(numInvocations: Int) = Mockito.atLeast(numInvocations) -fun atLeastOnce() = Mockito.atLeastOnce() -fun atMost(maxNumberOfInvocations: Int) = Mockito.atMost(maxNumberOfInvocations) -fun calls(wantedNumberOfInvocations: Int) = Mockito.calls(wantedNumberOfInvocations) +fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! +fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!! +fun atMost(maxNumberOfInvocations: Int): VerificationMode = Mockito.atMost(maxNumberOfInvocations)!! +fun calls(wantedNumberOfInvocations: Int): VerificationMode = Mockito.calls(wantedNumberOfInvocations)!! fun clearInvocations(vararg mocks: T) = Mockito.clearInvocations(*mocks) -fun description(description: String) = Mockito.description(description) +fun description(description: String): VerificationMode = Mockito.description(description) -fun doAnswer(answer: (InvocationOnMock) -> T?) = Mockito.doAnswer { answer(it) } +fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber = Mockito.doAnswer { answer(it) }!! -fun doCallRealMethod() = Mockito.doCallRealMethod() -fun doNothing() = Mockito.doNothing() -fun doReturn(value: Any) = Mockito.doReturn(value) -fun doReturn(toBeReturned: Any, vararg toBeReturnedNext: Any) = Mockito.doReturn(toBeReturned, *toBeReturnedNext) -fun doThrow(toBeThrown: KClass) = Mockito.doThrow(toBeThrown.java) -fun doThrow(vararg toBeThrown: Throwable) = Mockito.doThrow(*toBeThrown) +fun doCallRealMethod(): Stubber = Mockito.doCallRealMethod()!! +fun doNothing(): Stubber = Mockito.doNothing()!! +fun doReturn(value: Any): Stubber = Mockito.doReturn(value)!! +fun doReturn(toBeReturned: Any, vararg toBeReturnedNext: Any): Stubber = Mockito.doReturn(toBeReturned, *toBeReturnedNext)!! +fun doThrow(toBeThrown: KClass): Stubber = Mockito.doThrow(toBeThrown.java)!! +fun doThrow(vararg toBeThrown: Throwable): Stubber = Mockito.doThrow(*toBeThrown)!! -inline fun eq(value: T) = Mockito.eq(value) ?: createInstance() -fun ignoreStubs(vararg mocks: Any) = Mockito.ignoreStubs(*mocks) -fun inOrder(vararg mocks: Any) = Mockito.inOrder(*mocks) +inline fun eq(value: T): T = Mockito.eq(value) ?: createInstance() +fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks)!! +fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! -inline fun isA() = Mockito.isA(T::class.java) -inline fun isNotNull() = Mockito.isNotNull(T::class.java) +inline fun isA(): T? = Mockito.isA(T::class.java) +inline fun isNotNull(): T? = Mockito.isNotNull(T::class.java) inline fun isNull(): T? = Mockito.isNull(T::class.java) inline fun mock(): T = Mockito.mock(T::class.java)!! @@ -74,29 +80,28 @@ inline fun mock(defaultAnswer: Answer): T = Mockito.mock( inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! inline fun mock(s: String): T = Mockito.mock(T::class.java, s)!! -fun mockingDetails(toInspect: Any) = Mockito.mockingDetails(toInspect) -fun never() = Mockito.never() -inline fun notNull() = Mockito.notNull(T::class.java) -fun only() = Mockito.only() -fun refEq(value: T, vararg excludeFields: String) = Mockito.refEq(value, *excludeFields) +fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! +fun never(): VerificationMode = Mockito.never()!! +inline fun notNull(): T? = Mockito.notNull(T::class.java) +fun only(): VerificationMode = Mockito.only()!! +fun refEq(value: T, vararg excludeFields: String): T? = Mockito.refEq(value, *excludeFields) -fun reset() = Mockito.reset() fun reset(vararg mocks: T) = Mockito.reset(*mocks) -fun same(value: T) = Mockito.same(value) +fun same(value: T): T? = Mockito.same(value) -inline fun spy() = Mockito.spy(T::class.java) -fun spy(value: T) = Mockito.spy(value) +inline fun spy(): T = Mockito.spy(T::class.java)!! +fun spy(value: T): T = Mockito.spy(value)!! -fun stub(methodCall: T) = Mockito.stub(methodCall) -fun timeout(millis: Long) = Mockito.timeout(millis) -fun times(numInvocations: Int) = Mockito.times(numInvocations) +fun stub(methodCall: T): DeprecatedOngoingStubbing = Mockito.stub(methodCall)!! +fun timeout(millis: Long): VerificationWithTimeout = Mockito.timeout(millis)!! +fun times(numInvocations: Int): VerificationMode = Mockito.times(numInvocations)!! fun validateMockitoUsage() = Mockito.validateMockitoUsage() -fun verify(mock: T) = Mockito.verify(mock) -fun verify(mock: T, mode: VerificationMode) = Mockito.verify(mock, mode) +fun verify(mock: T): T = Mockito.verify(mock)!! +fun verify(mock: T, mode: VerificationMode): T = Mockito.verify(mock, mode)!! fun verifyNoMoreInteractions(vararg mocks: T) = Mockito.verifyNoMoreInteractions(*mocks) fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(*mocks) -fun whenever(methodCall: T) = Mockito.`when`(methodCall) -fun withSettings() = Mockito.withSettings() +fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! +fun withSettings(): MockSettings = Mockito.withSettings()!! -- cgit v1.2.3 From 6a521ea6adbd06868c101815992dcf738e6ff987 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 26 Jul 2016 21:31:35 +0200 Subject: Make `doReturn` accept null values. Fixes #34. --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 4 ++-- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 11e5f81..cab95db 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -62,8 +62,8 @@ fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber = Mockito.doAnswer { fun doCallRealMethod(): Stubber = Mockito.doCallRealMethod()!! fun doNothing(): Stubber = Mockito.doNothing()!! -fun doReturn(value: Any): Stubber = Mockito.doReturn(value)!! -fun doReturn(toBeReturned: Any, vararg toBeReturnedNext: Any): Stubber = Mockito.doReturn(toBeReturned, *toBeReturnedNext)!! +fun doReturn(value: Any?): Stubber = Mockito.doReturn(value)!! +fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber = Mockito.doReturn(toBeReturned, *toBeReturnedNext)!! fun doThrow(toBeThrown: KClass): Stubber = Mockito.doThrow(toBeThrown.java)!! fun doThrow(vararg toBeThrown: Throwable): Stubber = Mockito.doThrow(*toBeThrown)!! diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index ef635b3..e8263a5 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -230,6 +230,25 @@ class MockitoTest { expect(mock.stringResult()).toBe("test") } + @Test + fun testDoReturnNullValue() { + val mock = mock() + + doReturn(null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnNullValues() { + val mock = mock() + + doReturn(null, null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + expect(mock.stringResult()).toBeNull() + } + @Test fun testDoReturnValues() { val mock = mock() -- cgit v1.2.3 From 51385cadfd8cc02232d8b69538f1db32b172bd5e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 26 Jul 2016 22:01:47 +0200 Subject: Added an example to the Readme on Argument Captors. Fixes #52. --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index b046e82..7dcfdb1 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,18 @@ For example: verify(myClass).setItems(argThat{ size == 2 }) ``` +### Argument Captors + +Argument Captors can be used to capture argument values for further assertions. +For example: + +```kotlin +verify(myClass).setItems(capture { items -> + assertEquals(2, items.size) + assertEquals("test", items[0]) +}) +``` + ### Convenience functions Most of Mockito's static functions are available as top-level functions. -- cgit v1.2.3 From 2f94f52b2ffd5912517844f331ac88c08da53cb3 Mon Sep 17 00:00:00 2001 From: Steve Hill Date: Tue, 9 Aug 2016 12:40:44 -0700 Subject: Upgrade Mockito to 2.0.99-beta * org.mockito.internal.util.MockUtil is now a static utility class * org.mockito.Mockito#stub has been removed in favor of #when --- mockito-kotlin/build.gradle | 2 +- .../src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt | 2 +- mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 6c6bdb1..b3676bc 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -20,7 +20,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.0.52-beta" + compile "org.mockito:mockito-core:2.0.99-beta" /* Tests */ testCompile "junit:junit:4.12" diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 034d3e4..bcbb064 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -177,7 +177,7 @@ private fun KType.createNullableInstance(): T? { private fun Class.uncheckedMock(): T { val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl val creationSettings = impl.confirm(this) - return MockUtil().createMock(creationSettings).apply { + return MockUtil.createMock(creationSettings).apply { (this as MockMethodInterceptor.MockAccess).mockitoInterceptor = null } } diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index cab95db..a78fe11 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -31,7 +31,6 @@ import org.mockito.MockingDetails import org.mockito.Mockito import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Answer -import org.mockito.stubbing.DeprecatedOngoingStubbing import org.mockito.stubbing.OngoingStubbing import org.mockito.stubbing.Stubber import org.mockito.verification.VerificationMode @@ -93,7 +92,6 @@ fun same(value: T): T? = Mockito.same(value) inline fun spy(): T = Mockito.spy(T::class.java)!! fun spy(value: T): T = Mockito.spy(value)!! -fun stub(methodCall: T): DeprecatedOngoingStubbing = Mockito.stub(methodCall)!! fun timeout(millis: Long): VerificationWithTimeout = Mockito.timeout(millis)!! fun times(numInvocations: Int): VerificationMode = Mockito.times(numInvocations)!! fun validateMockitoUsage() = Mockito.validateMockitoUsage() -- cgit v1.2.3 From 2d4eef9902a8f56e2ea9fc083203bdf6cd8f2b52 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 19 Aug 2016 19:56:44 +0200 Subject: Accept a stubbing lambda in mock() See #47. --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 11 ++++++ mockito-kotlin/src/test/kotlin/MockitoTest.kt | 44 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index a78fe11..4fcdd37 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -79,6 +79,17 @@ inline fun mock(defaultAnswer: Answer): T = Mockito.mock( inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! inline fun mock(s: String): T = Mockito.mock(T::class.java, s)!! +inline fun mock(stubbing: KStubbing.() -> Unit): T + = Mockito.mock(T::class.java)!!.apply { stubbing(KStubbing(this)) } + +class KStubbing(private val mock: T) { + fun on(methodCall: R) = Mockito.`when`(methodCall) + fun on(methodCall: T.() -> R) = Mockito.`when`(mock.methodCall()) +} + +fun OngoingStubbing.doReturn(t: T) = thenReturn(t) +fun OngoingStubbing.doReturn(t: T, vararg ts: T) = thenReturn(t, *ts) + fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! fun never(): VerificationMode = Mockito.never()!! inline fun notNull(): T? = Mockito.notNull(T::class.java) diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index e8263a5..3d9c69f 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -282,4 +282,48 @@ class MockitoTest { mock.go() } } + + @Test + fun testMockStubbing_lambda() { + /* Given */ + val mock = mock() { + on { stringResult() }.doReturn("A") + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testMockStubbing_normalOverridesLambda() { + /* Given */ + val mock = mock() { + on { stringResult() }.doReturn("A") + } + whenever(mock.stringResult()).thenReturn("B") + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("B") + } + + @Test + fun testMockStubbing_methodCall() { + /* Given */ + val mock = mock() + mock { + on(mock.stringResult()).doReturn("A") + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } } -- cgit v1.2.3 From ecfaf582ca1b209a7122b9bed4af9d3e076cee31 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 19 Aug 2016 20:06:39 +0200 Subject: Add infix modifiers to doReturn methods --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 5 +++-- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 14 +++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 4fcdd37..d2be7ef 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -87,8 +87,9 @@ class KStubbing(private val mock: T) { fun on(methodCall: T.() -> R) = Mockito.`when`(mock.methodCall()) } -fun OngoingStubbing.doReturn(t: T) = thenReturn(t) -fun OngoingStubbing.doReturn(t: T, vararg ts: T) = thenReturn(t, *ts) +infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing = thenReturn(t) +fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing = thenReturn(t, *ts) +inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing = thenReturn(ts[0], *ts.drop(1).toTypedArray()) fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! fun never(): VerificationMode = Mockito.never()!! diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 3d9c69f..7320dac 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -287,7 +287,7 @@ class MockitoTest { fun testMockStubbing_lambda() { /* Given */ val mock = mock() { - on { stringResult() }.doReturn("A") + on { stringResult() } doReturn "A" } /* When */ @@ -326,4 +326,16 @@ class MockitoTest { /* Then */ expect(result).toBe("A") } + + @Test + fun doReturn_withSingleItemList() { + /* Given */ + val mock = mock { + on { stringResult() } doReturn listOf("a", "b") + } + + /* Then */ + expect(mock.stringResult()).toBe("a") + expect(mock.stringResult()).toBe("b") + } } -- cgit v1.2.3 From 6cf8557ca09aeead313a209208b9cb7d3993d29e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 19 Aug 2016 22:04:41 +0200 Subject: Update README.md --- README.md | 105 ++++++++++---------------------------------------------------- 1 file changed, 17 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index 7dcfdb1..b02f8ed 100644 --- a/README.md +++ b/README.md @@ -17,96 +17,25 @@ dependencies { } ``` -## Examples +## Example -### Creating mock instances - -Due to Kotlin's [reified type parameters](https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters), if the type can be inferred, you don't have to specify it explicitly: - -**Java**: -```java -MyClass c = mock(Myclass.class); -c.doSomething(mock(MyOtherClass.class)); -``` - -**Kotlin**: -```kotlin -val c : MyClass = mock() -c.doSomething(mock()) -``` - -If the type can't be inferred, you can pass it like so: - -```kotlin -val d = mock() -``` - - -### Expecting any value - -Mockito's `any(Class)` often returns `null` for non-primitive classes. -In Kotlin, this can be a problem due to its [null-safety](https://kotlinlang.org/docs/reference/null-safety.html) feature. -This library creates non-null instances when necessary. -Again, if the type can be inferred, you don't have to specify it explicitely: - -**Java**: -```java -verify(myClass).doSomething(any(String.class)); -``` - -**Kotlin**: -```kotlin -verify(myClass).doSomething(any()); // Non-nullable parameter type is inferred -``` - -For generic arrays, use the `anyArray()` method: - -```kotlin -verify(myClass).setItems(anyArray()) -``` - -## Custom instance creators - -There are some cases where Mockito-Kotlin cannot create an instance of a class. -This can for instance be when a constructor has some specific preconditions -for its parameters. -You can _register_ `instance creators` to overcome this: - -```kotlin -MockitoKotlin.registerInstanceCreator { MyClass(5) } -``` - -Whenever MockitoKotlin needs to create an instance of `MyClass`, this function is called, -giving you ultimate control over how these instances are created. - -These instance creators work on a per-file basis: for each of your test files -you will need to register them again. - -### Argument Matchers - -Using higher-order functions, you can write very clear expectations about expected values. -For example: - -**Kotlin**: -```kotlin -verify(myClass).setItems(argThat{ size == 2 }) -``` - -### Argument Captors - -Argument Captors can be used to capture argument values for further assertions. -For example: +A test using Mockito-Kotlin typically looks like the following: ```kotlin -verify(myClass).setItems(capture { items -> - assertEquals(2, items.size) - assertEquals("test", items[0]) -}) +@Test +fun a(){ + /* Given */ + val mock = mock { + on { getText() } doReturn "text" + } + val classUnderTest = ClassUnderTest(mock) + + /* When */ + classUnderText.doAction() + + /* Then */ + verify(mock).doSomething(any()) +} ``` -### Convenience functions - -Most of Mockito's static functions are available as top-level functions. -That means, IDE's like IntelliJ can easily import and autocomplete them, saving you the hassle of manually importing them. - - +For more info and samples, see the [Wiki](https://github.com/nhaarman/mockito-kotlin/wiki). -- cgit v1.2.3 From 6110a908c68e0deab98f80143a75df6406fb5553 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 11:28:19 +0200 Subject: Update Mockito version to 2.1.0-beta.125 --- build.gradle | 3 ++- mockito-kotlin/build.gradle | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index cc7ac90..43d7b15 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { - id "com.jfrog.bintray" version "1.5" + id "com.jfrog.bintray" version "1.5" + id 'com.github.ben-manes.versions' version '0.13.0' } apply plugin: 'maven' apply plugin: 'maven-publish' diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index b3676bc..8169f08 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -20,7 +20,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.0.99-beta" + compile "org.mockito:mockito-core:2.1.0-beta.125" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 58013d803355b0f92b8a552f037e45f0abddd3b9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 11:30:05 +0200 Subject: Update dependencies --- build.gradle | 2 +- mockito-kotlin/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 43d7b15..06fdf0f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id "com.jfrog.bintray" version "1.5" + id "com.jfrog.bintray" version "1.7.1" id 'com.github.ben-manes.versions' version '0.13.0' } apply plugin: 'maven' diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 8169f08..d35e710 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -24,7 +24,7 @@ dependencies { /* Tests */ testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:0.5.1" + testCompile "com.nhaarman:expect.kt:0.6.0" } publishing { -- cgit v1.2.3 From 855c14ba580ff86e128d34cc880079c5999b60fc Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 11:33:13 +0200 Subject: Update gradle wrapper to 3.0 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 554f6fe..46b1b27 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-all.zip -- cgit v1.2.3 From 18be9684c5264caea44261631c7db01dcc28163b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 11:20:02 +0200 Subject: Improve `easiestConstructor()` to sort by parameters size. --- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 20 +++++++------------- mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt | 13 +++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index bcbb064..99206a8 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -59,7 +59,7 @@ fun createInstance(kClass: KClass): T { kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() kClass.isEnum() -> kClass.java.enumConstants.first() kClass.isArray() -> kClass.toArrayInstance() - kClass.isClassObject() -> kClass.toClassObject() + kClass.isClassObject() -> kClass.toClassObject() else -> kClass.easiestConstructor().newInstance() } } @@ -68,20 +68,14 @@ fun createInstance(kClass: KClass): T { * Tries to find the easiest constructor which it can instantiate. */ private fun KClass.easiestConstructor(): KFunction { - return constructors.firstOrDefault( - { - it.parameters.filter { - it.type.toString().toLowerCase().contains("array") - }.isEmpty() - }, - { - constructors.sortedBy { it.parameters.size }.first() - } - ) + return constructors + .sortedBy { it.parameters.size } + .withoutArrayParameters() + .firstOrNull() ?: constructors.sortedBy { it.parameters.size }.first() } -private fun Collection.firstOrDefault(predicate: (T) -> Boolean, default: () -> T): T { - return firstOrNull(predicate) ?: default() +private fun List>.withoutArrayParameters() = filter { + it.parameters.filter { parameter -> parameter.type.toString().toLowerCase().contains("array") }.isEmpty() } @Suppress("SENSELESS_COMPARISON") diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index 75bddb1..a8207fc 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -424,6 +424,15 @@ class CreateInstanceTest { } } + @Test + fun defaultEmptyConstructor_takesSimplestConstructor() { + /* When */ + val result = createInstance(WithDefaultEmptyConstructor::class) + + /* Then */ + expect(result).toNotBeNull() + } + private class PrivateClass private constructor(val data: String) class ClosedClass @@ -459,5 +468,9 @@ class CreateInstanceTest { } } + class WithDefaultEmptyConstructor() { + constructor(c: ForbiddenConstructor) : this() + } + enum class MyEnum { VALUE, ANOTHER_VALUE } } -- cgit v1.2.3 From 400b1cc38e83d6ddce5923b044cf9fd0220946df Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 12:06:36 +0200 Subject: Deprecate methods that are deprecated in Mockito. --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 25 ++++++++++++++-------- .../src/test/kotlin/MockitoKotlinTest.kt | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index d2be7ef..264d1c1 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -41,12 +41,7 @@ fun after(millis: Long) = Mockito.after(millis) inline fun any() = Mockito.any(T::class.java) ?: createInstance() inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() -inline fun anyCollection(): Collection = Mockito.anyCollectionOf(T::class.java) -inline fun anyList(): List = Mockito.anyListOf(T::class.java) -inline fun anySet(): Set = Mockito.anySetOf(T::class.java) -inline fun anyMap(): Map = Mockito.anyMapOf(K::class.java, V::class.java) -inline fun anyVararg() = Mockito.anyVararg() ?: createInstance() - +inline fun anyVararg(): T = Mockito.any() ?: createInstance() inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! @@ -71,8 +66,8 @@ fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks) fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! inline fun isA(): T? = Mockito.isA(T::class.java) -inline fun isNotNull(): T? = Mockito.isNotNull(T::class.java) -inline fun isNull(): T? = Mockito.isNull(T::class.java) +fun isNotNull(): T? = Mockito.isNotNull() +fun isNull(): T? = Mockito.isNull() inline fun mock(): T = Mockito.mock(T::class.java)!! inline fun mock(defaultAnswer: Answer): T = Mockito.mock(T::class.java, defaultAnswer)!! @@ -93,7 +88,7 @@ inline infix fun OngoingStubbing.doReturn(ts: List): OngoingSt fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! fun never(): VerificationMode = Mockito.never()!! -inline fun notNull(): T? = Mockito.notNull(T::class.java) +fun notNull(): T? = Mockito.notNull() fun only(): VerificationMode = Mockito.only()!! fun refEq(value: T, vararg excludeFields: String): T? = Mockito.refEq(value, *excludeFields) @@ -115,3 +110,15 @@ fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(* fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! fun withSettings(): MockSettings = Mockito.withSettings()!! + +@Deprecated("Use any() instead.", ReplaceWith("any()")) +inline fun anyCollection(): Collection = any() + +@Deprecated("Use any() instead.", ReplaceWith("any()")) +inline fun anyList(): List = any() + +@Deprecated("Use any() instead.", ReplaceWith("any()")) +inline fun anySet(): Set = any() + +@Deprecated("Use any() instead.", ReplaceWith("any()")) +inline fun anyMap(): Map = any() diff --git a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt index 7f80565..3b5774f 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt @@ -54,6 +54,6 @@ class MockitoKotlinTest { val result = createInstance() /* Then */ - expect(result).toNotBeReferentially(closed) + expect(result).toNotBeTheSameAs(closed) } } -- cgit v1.2.3 From 7dcebc913be37a66392d634f3558bcb698413230 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 12:21:27 +0200 Subject: Stop. Sending me. Emails. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 150dc86..608fe0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,3 +14,6 @@ install: script: - ./gradlew test + +notifications: + email: false \ No newline at end of file -- cgit v1.2.3 From 9507a2077c76b71f7ecf2e0cd7bcb5ab6c19078d Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 12:17:56 +0200 Subject: Make anyArray() accept nullable types. --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 2 +- mockito-kotlin/src/test/kotlin/Classes.kt | 1 + mockito-kotlin/src/test/kotlin/MockitoTest.kt | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 264d1c1..3be50d9 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -40,7 +40,7 @@ import kotlin.reflect.KClass fun after(millis: Long) = Mockito.after(millis) inline fun any() = Mockito.any(T::class.java) ?: createInstance() -inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() +inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() inline fun anyVararg(): T = Mockito.any() ?: createInstance() inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index d494872..2f066f3 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -43,6 +43,7 @@ interface Methods { fun intArray(i: IntArray) fun closed(c: Closed) fun closedArray(a: Array) + fun closedNullableArray(a: Array) fun closedCollection(c: Collection) fun closedList(c: List) fun closedStringMap(m: Map) diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 7320dac..e5c2eb2 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -64,6 +64,14 @@ class MockitoTest { } } + @Test + fun anyNullableClassArray() { + mock().apply { + closedNullableArray(arrayOf(Closed(), null)) + verify(this).closedNullableArray(anyArray()) + } + } + @Test fun anyCollectionOfClosed() { mock().apply { -- cgit v1.2.3 From 9a3b7de2929e1cdf1d56e8595b07ce3ef2be8cb2 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 12:30:15 +0200 Subject: Introduce argForWhich() as an alias for argThat() --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 1 + mockito-kotlin/src/test/kotlin/MockitoTest.kt | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 3be50d9..d23806c 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -43,6 +43,7 @@ inline fun any() = Mockito.any(T::class.java) ?: createInstanc inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() inline fun anyVararg(): T = Mockito.any() ?: createInstance() inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) +inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!! diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index e5c2eb2..2c50060 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -133,6 +133,15 @@ class MockitoTest { }) } } + @Test + fun listArgForWhich() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList(argForWhich { + size == 2 + }) + } + } @Test fun atLeastXInvocations() { -- cgit v1.2.3 From 650e293e17989f9394a49683b99a9b7e292680d0 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 9 Sep 2016 12:45:09 +0200 Subject: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b02f8ed..e442252 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ fun a(){ val classUnderTest = ClassUnderTest(mock) /* When */ - classUnderText.doAction() + classUnderTest.doAction() /* Then */ verify(mock).doSomething(any()) -- cgit v1.2.3 From 6862ea50ffeb79c5920146a0e196c23550753234 Mon Sep 17 00:00:00 2001 From: John Shelley Date: Sat, 17 Sep 2016 22:26:32 -0500 Subject: update to RC.1 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index d35e710..f8a150f 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -20,7 +20,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.1.0-beta.125" + compile "org.mockito:mockito-core:2.1.0-RC.1" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 935184006b5a9951ee0e448da23d74e7c101269a Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 21 Sep 2016 19:21:36 +0200 Subject: Include `anyOrNull()` --- .../main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 7 ++++++- mockito-kotlin/src/test/kotlin/Classes.kt | 1 + mockito-kotlin/src/test/kotlin/MockitoTest.kt | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index d23806c..7b520fe 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -39,9 +39,14 @@ import kotlin.reflect.KClass fun after(millis: Long) = Mockito.after(millis) +/** Matches any object, excluding nulls. */ inline fun any() = Mockito.any(T::class.java) ?: createInstance() -inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() +/** Matches anything, including nulls. */ +inline fun anyOrNull(): T = Mockito.any() ?: createInstance() +/** Matches any vararg object, including nulls. */ inline fun anyVararg(): T = Mockito.any() ?: createInstance() +/** Matches any array of type T. */ +inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index 2f066f3..9107ebc 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -51,6 +51,7 @@ interface Methods { fun string(s: String) fun closedVararg(vararg c: Closed) fun throwableClass(t: ThrowableClass) + fun nullableString(s: String?) fun stringResult(): String } diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 2c50060..9d3a5fa 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -116,6 +116,22 @@ class MockitoTest { } } + @Test + fun anyNull_neverVerifiesAny() { + mock().apply { + nullableString(null) + verify(this, never()).nullableString(any()) + } + } + + @Test + fun anyNull_verifiesAnyOrNull() { + mock().apply { + nullableString(null) + verify(this).nullableString(anyOrNull()) + } + } + @Test fun anyThrowableWithSingleThrowableConstructor() { mock().apply { @@ -133,6 +149,7 @@ class MockitoTest { }) } } + @Test fun listArgForWhich() { mock().apply { -- cgit v1.2.3 From f2ed0040189b30d9c1b68e01fcf5fe46e5ee5d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Soares?= Date: Thu, 22 Sep 2016 14:38:11 -0300 Subject: Upgrade Kotlin to 1.0.4. --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index f8a150f..5f512c2 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'kotlin' buildscript { - ext.kotlin_version = '1.0.3' + ext.kotlin_version = '1.0.4' repositories { mavenCentral() -- cgit v1.2.3 From 0886485a15e3212fee45aaedfdac06529afeacdb Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 3 Oct 2016 14:12:32 +0200 Subject: Update Mockito dependency to RC2 --- mockito-kotlin/build.gradle | 2 +- .../src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 5f512c2..acde7e0 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -20,7 +20,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.1.0-RC.1" + compile "org.mockito:mockito-core:2.1.0-RC.2" /* Tests */ testCompile "junit:junit:4.12" diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 99206a8..0ce613c 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -27,7 +27,7 @@ package com.nhaarman.mockito_kotlin import org.mockito.Answers import org.mockito.internal.creation.MockSettingsImpl -import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor +import org.mockito.internal.creation.bytebuddy.MockAccess import org.mockito.internal.util.MockUtil import java.lang.reflect.InvocationTargetException import java.lang.reflect.Modifier @@ -172,6 +172,6 @@ private fun Class.uncheckedMock(): T { val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl val creationSettings = impl.confirm(this) return MockUtil.createMock(creationSettings).apply { - (this as MockMethodInterceptor.MockAccess).mockitoInterceptor = null + (this as MockAccess).mockitoInterceptor = null } } -- cgit v1.2.3 From e549d8d9b2622ea96e01c5834dd3f6111e9d0bde Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 3 Oct 2016 19:00:52 +0200 Subject: Update Mockito dependency to 2.1.0 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index acde7e0..a00aaac 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -20,7 +20,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.1.0-RC.2" + compile "org.mockito:mockito-core:2.1.0" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 0c3e137a984b38913a34415e4c617843b6c0f2ba Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 3 Oct 2016 19:09:59 +0200 Subject: Provide mock instance to stubbing method in mock() This will allow access to the mock inside the stubbing. For example: mock { mock -> on { method() } doReturn mock } --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 11 +++++++++-- mockito-kotlin/src/test/kotlin/Classes.kt | 1 + mockito-kotlin/src/test/kotlin/MockitoTest.kt | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 7b520fe..a35ce02 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -41,12 +41,16 @@ fun after(millis: Long) = Mockito.after(millis) /** Matches any object, excluding nulls. */ inline fun any() = Mockito.any(T::class.java) ?: createInstance() + /** Matches anything, including nulls. */ inline fun anyOrNull(): T = Mockito.any() ?: createInstance() + /** Matches any vararg object, including nulls. */ inline fun anyVararg(): T = Mockito.any() ?: createInstance() + /** Matches any array of type T. */ inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() + inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) @@ -80,8 +84,11 @@ inline fun mock(defaultAnswer: Answer): T = Mockito.mock( inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! inline fun mock(s: String): T = Mockito.mock(T::class.java, s)!! -inline fun mock(stubbing: KStubbing.() -> Unit): T - = Mockito.mock(T::class.java)!!.apply { stubbing(KStubbing(this)) } +inline fun mock(stubbing: KStubbing.(T) -> Unit): T { + return mock().apply { + KStubbing(this).stubbing(this) + } +} class KStubbing(private val mock: T) { fun on(methodCall: R) = Mockito.`when`(methodCall) diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index 9107ebc..979c71b 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -54,6 +54,7 @@ interface Methods { fun nullableString(s: String?) fun stringResult(): String + fun builderMethod() : Methods } class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 9d3a5fa..c40f952 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -361,6 +361,20 @@ class MockitoTest { expect(result).toBe("A") } + @Test + fun testMockStubbing_builder() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doReturn mock + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBeTheSameAs(mock) + } + @Test fun doReturn_withSingleItemList() { /* Given */ -- cgit v1.2.3 From 1d65fc06636aa2a191d5375b76a2a9bb98bfc630 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 3 Oct 2016 19:19:03 +0200 Subject: Strip methods from file identifiers. --- .../com/nhaarman/mockito_kotlin/MockitoKotlin.kt | 4 +++- .../src/test/kotlin/MockitoKotlinTest.kt | 23 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt index 2158d7a..6c07cf6 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt @@ -78,6 +78,8 @@ class MockitoKotlin { ?.second } - private fun StackTraceElement.toFileIdentifier() = "$fileName$className" + private fun StackTraceElement.toFileIdentifier() = "$fileName$className".let { + if (it.contains("$")) it.substring(0..it.indexOf("$") - 1) else it + } } } diff --git a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt index 3b5774f..b0465d1 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt @@ -24,12 +24,17 @@ */ import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.MockitoKotlin -import com.nhaarman.mockito_kotlin.createInstance +import com.nhaarman.mockito_kotlin.* +import org.junit.After import org.junit.Test class MockitoKotlinTest { + @After + fun teardown() { + MockitoKotlin.resetInstanceCreators() + } + @Test fun register() { /* Given */ @@ -56,4 +61,18 @@ class MockitoKotlinTest { /* Then */ expect(result).toNotBeTheSameAs(closed) } + + @Test + fun usingInstanceCreatorInsideLambda() { + MockitoKotlin.registerInstanceCreator { CreateInstanceTest.ForbiddenConstructor(2) } + + mock { + on { doSomething(any()) } doReturn "" + } + } + + interface TestClass { + + fun doSomething(c: CreateInstanceTest.ForbiddenConstructor): String + } } -- cgit v1.2.3 From 6965414e1f1921cd4a0bfec09e2d107dd515e9ff Mon Sep 17 00:00:00 2001 From: desilvai Date: Mon, 10 Oct 2016 21:37:53 -0500 Subject: Fix compatibility with mock-maker-inline for mocking final classes This includes a check for whether the resource file containing 'mock-maker-inline' is present to determine whether or not a class is mockable. It also adds an instanceof check before trying to cast an unchecked mock to a MockAccess object. --- mockito-kotlin/build.gradle | 85 ++++++----------- mockito-kotlin/publishing.gradle | 44 +++++++++ .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 22 ++++- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 1 + .../kotlin/CreateInstanceOfImmutableTest.kt | 106 +++++++++++++++++++++ .../org.mockito.plugins.MockMaker | 1 + 6 files changed, 202 insertions(+), 57 deletions(-) create mode 100644 mockito-kotlin/publishing.gradle create mode 100644 mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt create mode 100644 mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index a00aaac..795d777 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,73 +1,50 @@ apply plugin: 'kotlin' +apply from: './publishing.gradle' buildscript { - ext.kotlin_version = '1.0.4' + ext.kotlin_version = '1.0.4' - repositories { - mavenCentral() - } + repositories { + mavenCentral() + } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } } repositories { - mavenCentral() - jcenter() -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.1.0" - - /* Tests */ - testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:0.6.0" + mavenCentral() + jcenter() } -publishing { - publications { - MyPublication(MavenPublication) { - from components.java - artifact javadocJar - artifact sourcesJar - - groupId 'com.nhaarman' - artifactId 'mockito-kotlin' - version rootProject.ext.versionName +sourceSets { + testInlineMockito { + compileClasspath += main.output + test.output + runtimeClasspath += main.output + test.output } - } } -bintray { - user = hasProperty('bintray_user') ? bintray_user : System.getenv('BINTRAY_USER') - key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') - publications = ['MyPublication'] +configurations { + testInlineMockitoCompile.extendsFrom testCompile + testInlineMockitoRuntime.extendsFrom testRuntime +} - pkg { - repo = 'maven' - name = "Mockito-Kotlin" - desc = "Using Mockito with Kotlin" +// define custom test task for running integration tests +task testInlineMockito(type: Test) { + testClassesDir = sourceSets.testInlineMockito.output.classesDir + classpath = sourceSets.testInlineMockito.runtimeClasspath +} - licenses = ['MIT'] - vcsUrl = 'https://github.com/bintray/gradle-bintray-plugin.git' +test.dependsOn testInlineMockito - version { - name = rootProject.ext.versionName - desc = 'Using Mockito with Kotlin' - vcsTag = rootProject.ext.versionName - } - } -} -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from 'build/docs/javadoc' -} +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" + compile "org.mockito:mockito-core:2.1.0" -task sourcesJar(type: Jar) { - from sourceSets.main.allSource - classifier = 'sources' + /* Tests */ + testCompile "junit:junit:4.12" + testCompile "com.nhaarman:expect.kt:0.6.0" } diff --git a/mockito-kotlin/publishing.gradle b/mockito-kotlin/publishing.gradle new file mode 100644 index 0000000..4fa0657 --- /dev/null +++ b/mockito-kotlin/publishing.gradle @@ -0,0 +1,44 @@ +publishing { + publications { + MyPublication(MavenPublication) { + from components.java + artifact javadocJar + artifact sourcesJar + + groupId 'com.nhaarman' + artifactId 'mockito-kotlin' + version rootProject.ext.versionName + } + } +} + +bintray { + user = hasProperty('bintray_user') ? bintray_user : System.getenv('BINTRAY_USER') + key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') + publications = ['MyPublication'] + + pkg { + repo = 'maven' + name = "Mockito-Kotlin" + desc = "Using Mockito with Kotlin" + + licenses = ['MIT'] + vcsUrl = 'https://github.com/bintray/gradle-bintray-plugin.git' + + version { + name = rootProject.ext.versionName + desc = 'Using Mockito with Kotlin' + vcsTag = rootProject.ext.versionName + } + } +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from 'build/docs/javadoc' +} + +task sourcesJar(type: Jar) { + from sourceSets.main.allSource + classifier = 'sources' +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 0ce613c..f6c5017 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -29,6 +29,7 @@ import org.mockito.Answers import org.mockito.internal.creation.MockSettingsImpl import org.mockito.internal.creation.bytebuddy.MockAccess import org.mockito.internal.util.MockUtil +import java.io.File import java.lang.reflect.InvocationTargetException import java.lang.reflect.Modifier import java.lang.reflect.ParameterizedType @@ -46,6 +47,18 @@ import kotlin.reflect.jvm.jvmName * classes to avoid NPE's when using Mockito with Kotlin. */ +/** + * Checks whether the resource file to enable mocking of final classes is present. + */ +private var mockMakerInlineEnabled: Boolean? = null +private fun mockMakerInlineEnabled(jClass: Class): Boolean { + return mockMakerInlineEnabled ?: + jClass.getResource("mockito-extensions/org.mockito.plugins.MockMaker")?.let { + mockMakerInlineEnabled = File(it.file).readLines().filter { it == "mock-maker-inline" }.isNotEmpty() + mockMakerInlineEnabled + } ?: false +} + inline fun createArrayInstance() = arrayOf() inline fun createInstance() = createInstance(T::class) @@ -81,7 +94,10 @@ private fun List>.withoutArrayParameters() = filter { @Suppress("SENSELESS_COMPARISON") private fun KClass<*>.hasObjectInstance() = objectInstance != null -private fun KClass<*>.isMockable() = !Modifier.isFinal(java.modifiers) +private fun KClass<*>.isMockable(): Boolean { + return !Modifier.isFinal(java.modifiers) || mockMakerInlineEnabled(java) +} + private fun KClass<*>.isEnum() = java.isEnum private fun KClass<*>.isArray() = java.isArray private fun KClass<*>.isClassObject() = jvmName.equals("java.lang.Class") @@ -168,10 +184,10 @@ private fun KType.createNullableInstance(): T? { * Creates a mock instance of given class, without modifying or checking any internal Mockito state. */ @Suppress("UNCHECKED_CAST") -private fun Class.uncheckedMock(): T { +fun Class.uncheckedMock(): T { val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl val creationSettings = impl.confirm(this) return MockUtil.createMock(creationSettings).apply { - (this as MockAccess).mockitoInterceptor = null + (this as? MockAccess)?.mockitoInterceptor = null } } diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index c40f952..75d7cbd 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -132,6 +132,7 @@ class MockitoTest { } } + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ @Test fun anyThrowableWithSingleThrowableConstructor() { mock().apply { diff --git a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt new file mode 100644 index 0000000..a5abaf8 --- /dev/null +++ b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt @@ -0,0 +1,106 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Ian J. De Silva + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.* +import org.junit.Test +import java.io.IOException +import java.math.BigInteger + +class CreateInstanceOfImmutableTest { + + class ClassToBeMocked { + + fun doSomething(c: ClassToBeMocked) { + } + + fun doSomethingElse(value: BigInteger): BigInteger { + return value.plus(BigInteger.ONE) + } + } + + @Test + fun mockClosedClass() { + /* When */ + val result = mock() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass() { + /* Given */ + val mock = mock() + + /* When */ + mock.doSomething(mock) + + /* Then */ + verify(mock).doSomething(any()) + } + + @Test + fun mockClosedFunction_mockStubbing() { + /* Given */ + val mock = mock { + on { doSomethingElse(any()) } doReturn (BigInteger.ONE) + } + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + @Test + fun mockClosedFunction_whenever() { + /* Given */ + val mock = mock() + whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ + @Test + fun anyThrowableWithSingleThrowableConstructor() { + mock().apply { + throwableClass(ThrowableClass(IOException())) + verify(this).throwableClass(any()) + } + } + + interface Methods { + + fun throwableClass(t: ThrowableClass) + } + + class ThrowableClass(cause: Throwable) : Throwable(cause) +} diff --git a/mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker b/mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file -- cgit v1.2.3 From 94b3c652833caf4066aa7203d6cabf4631eae1af Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 13 Oct 2016 13:39:52 +0200 Subject: Added doThrow methods to OngoingStubbing --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 5 ++ mockito-kotlin/src/test/kotlin/MockitoTest.kt | 75 ++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index a35ce02..e674d75 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -99,6 +99,11 @@ infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing = thenReturn fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing = thenReturn(t, *ts) inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing = thenReturn(ts[0], *ts.drop(1).toTypedArray()) +infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing = thenThrow(t) +fun OngoingStubbing.doThrow(t: Throwable, vararg ts: Throwable): OngoingStubbing = thenThrow(t, *ts) +infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing = thenThrow(t.java) +fun OngoingStubbing.doThrow(t: KClass, vararg ts: KClass): OngoingStubbing = thenThrow(t.java, *ts.map { it.java }.toTypedArray()) + fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! fun never(): VerificationMode = Mockito.never()!! fun notNull(): T? = Mockito.notNull() diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 75d7cbd..65d9ed1 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -1,5 +1,6 @@ import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.expect.fail import com.nhaarman.mockito_kotlin.* import org.junit.Test import org.mockito.exceptions.base.MockitoAssertionError @@ -376,6 +377,80 @@ class MockitoTest { expect(result).toBeTheSameAs(mock) } + @Test + fun testMockStubbing_doThrow() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doThrow IllegalArgumentException() + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + } + + @Test + fun testMockStubbing_doThrowClass() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doThrow IllegalArgumentException::class + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + } + + @Test + fun testMockStubbing_doThrowVarargs() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() }.doThrow(IllegalArgumentException(), UnsupportedOperationException()) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: UnsupportedOperationException) { + } + } + + @Test + fun testMockStubbing_doThrowClassVarargs() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() }.doThrow(IllegalArgumentException::class, UnsupportedOperationException::class) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: UnsupportedOperationException) { + } + } + @Test fun doReturn_withSingleItemList() { /* Given */ -- cgit v1.2.3 From 80dbefd3cc15be951863999c0e7b86a2b63ba12e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 13 Oct 2016 15:13:35 +0200 Subject: Improve argument captors The capture { } method's behavior did not match the Java behavior. For capturing single values, use one of the following: - argThat(T.() -> Boolean) - argForWhich(T.() -> Boolean) - check((T) -> Unit) For capturing multiple values, use `argumentCaptor()` in the traditional Java way. --- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 25 ++++++++++++++++++++- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 1 + .../src/test/kotlin/ArgumentCaptorTest.kt | 26 ++++++++++++++-------- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 10 +++++++++ 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt index 3f52785..dcbbe43 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt @@ -26,9 +26,32 @@ package com.nhaarman.mockito_kotlin import org.mockito.ArgumentCaptor +import kotlin.reflect.KClass + +inline fun argumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) -inline fun argumentCaptor() = ArgumentCaptor.forClass(T::class.java) inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() + +@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()")) +inline fun capture(captor: KArgumentCaptor): T = captor.capture() + +class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass) { + + val value: T + get() = captor.value + + val allValues: List + get() = captor.allValues + + fun capture(): T = captor.capture() ?: createInstance(tClass) +} + +/** + * 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.") inline fun capture(noinline consumer: (T) -> Unit): T { var times = 0 return argThat { if (++times == 1) consumer.invoke(this); true } diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index e674d75..dc6e67b 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -53,6 +53,7 @@ inline fun anyArray(): Array = Mockito.any(Array::class inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) +inline fun check(noinline predicate: (T) -> Unit) = Mockito.argThat { it -> predicate(it); true } ?: createInstance(T::class) fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!! diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt index 12a794a..5a176dc 100644 --- a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt +++ b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt @@ -1,8 +1,8 @@ +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.expect.expect -import com.nhaarman.mockito_kotlin.capture import org.junit.Test import java.util.* @@ -10,22 +10,30 @@ class ArgumentCaptorTest { @Test fun explicitCaptor() { + /* Given */ val date: Date = mock() - val time = argumentCaptor() + /* When */ date.time = 5L - verify(date).time = capture(time) - expect(time.value).toBe(5L) + /* Then */ + val captor = argumentCaptor() + verify(date).time = captor.capture() + expect(captor.value).toBe(5L) } @Test - fun implicitCaptor() { + fun argumentCaptor_multipleValues() { + /* Given */ val date: Date = mock() + + /* When */ date.time = 5L + date.time = 7L - verify(date).time = capture { - expect(it).toBe(5L) - } + /* Then */ + val captor = argumentCaptor() + verify(date, times(2)).time = captor.capture() + expect(captor.allValues).toBe(listOf(5, 7)) } } \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 65d9ed1..897e0d3 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -162,6 +162,16 @@ class MockitoTest { } } + @Test + fun listArgCheck() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList(check { + expect(it.size).toBe(2) + }) + } + } + @Test fun atLeastXInvocations() { mock().apply { -- cgit v1.2.3 From 0b43d0b9b40122fa4286336db459068c2177560b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 13 Oct 2016 15:33:27 +0200 Subject: Use the java class' name to create an array instance --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt | 7 ++++++- mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt | 7 +++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index f6c5017..07bf704 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -41,6 +41,7 @@ import kotlin.reflect.defaultType import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaType import kotlin.reflect.jvm.jvmName +import java.lang.reflect.Array as JavaArray /** * A collection of functions that tries to create an instance of @@ -51,6 +52,7 @@ import kotlin.reflect.jvm.jvmName * Checks whether the resource file to enable mocking of final classes is present. */ private var mockMakerInlineEnabled: Boolean? = null + private fun mockMakerInlineEnabled(jClass: Class): Boolean { return mockMakerInlineEnabled ?: jClass.getResource("mockito-extensions/org.mockito.plugins.MockMaker")?.let { @@ -137,7 +139,10 @@ private fun KClass.toArrayInstance(): T { "LongArray" -> longArrayOf() "DoubleArray" -> doubleArrayOf() "FloatArray" -> floatArrayOf() - else -> throw UnsupportedOperationException("Cannot create a generic array for $simpleName. Use createArrayInstance() or anyArray() instead.") + else -> { + val name = java.name.drop(2).dropLast(1) + return JavaArray.newInstance(Class.forName(name), 0) as T + } } as T } diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index a8207fc..1cae9ff 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -159,10 +159,13 @@ class CreateInstanceTest { expect(result).toNotBeNull() } - @Test(expected = UnsupportedOperationException::class) + @Test fun classArray_usingAny() { /* When */ - createInstance>() + val result = createInstance>() + + /* Then */ + expect(result).toBeInstanceOf>() } @Test -- cgit v1.2.3 From d5566910f64687935596ab127de6502536618a8b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 13 Oct 2016 15:42:21 +0200 Subject: Update Mockito to 2.2.1 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 795d777..9337dde 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -42,7 +42,7 @@ test.dependsOn testInlineMockito dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.1.0" + compile "org.mockito:mockito-core:2.2.1" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 8e083adda1c2b2a49a76e8f2c4db990867cadcb6 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 20 Oct 2016 22:52:33 +0200 Subject: Publish to Maven Central instead of Bintray --- README.md | 6 +-- RELEASING.md | 6 +++ build.gradle | 3 -- mockito-kotlin/publishing.gradle | 91 ++++++++++++++++++++++++++-------------- 4 files changed, 68 insertions(+), 38 deletions(-) create mode 100644 RELEASING.md diff --git a/README.md b/README.md index e442252..8a951f2 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,12 @@ A small library that provides helper functions to work with [Mockito](https://gi ## Install -Mockito-Kotlin is available on JCenter. -For Gradle users, add the following to your `build.gradle`: +Mockito-Kotlin is available on Maven Central. +For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` with the latest version: ```groovy repositories { - jcenter() + mavenCentral() } dependencies { testCompile "com.nhaarman:mockito-kotlin:x.x.x" diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..49f0d01 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,6 @@ +To publish a release: + + - Tag the commit on master: `git tag -a x.x.x -m x.x.x && git push --tags` + - Execute the release process: `./gradlew clean test uploadArchives -PisRelease=true` + - Head to https://oss.sonatype.org/#stagingRepositories to close and release the deployment. + - Don't forget to publish the tag on Github with release notes :) \ No newline at end of file diff --git a/build.gradle b/build.gradle index 06fdf0f..dae319a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,5 @@ plugins { - id "com.jfrog.bintray" version "1.7.1" id 'com.github.ben-manes.versions' version '0.13.0' } -apply plugin: 'maven' -apply plugin: 'maven-publish' apply from: 'gradle/scripts/tagging.gradle' diff --git a/mockito-kotlin/publishing.gradle b/mockito-kotlin/publishing.gradle index 4fa0657..3b08ab8 100644 --- a/mockito-kotlin/publishing.gradle +++ b/mockito-kotlin/publishing.gradle @@ -1,37 +1,11 @@ -publishing { - publications { - MyPublication(MavenPublication) { - from components.java - artifact javadocJar - artifact sourcesJar - - groupId 'com.nhaarman' - artifactId 'mockito-kotlin' - version rootProject.ext.versionName - } - } -} +apply plugin: 'maven' +apply plugin: 'signing' -bintray { - user = hasProperty('bintray_user') ? bintray_user : System.getenv('BINTRAY_USER') - key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') - publications = ['MyPublication'] +group = 'com.nhaarman' +version = rootProject.ext.versionName +def sonatypeUsername = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') +def sonatypePassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') - pkg { - repo = 'maven' - name = "Mockito-Kotlin" - desc = "Using Mockito with Kotlin" - - licenses = ['MIT'] - vcsUrl = 'https://github.com/bintray/gradle-bintray-plugin.git' - - version { - name = rootProject.ext.versionName - desc = 'Using Mockito with Kotlin' - vcsTag = rootProject.ext.versionName - } - } -} task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' @@ -41,4 +15,57 @@ task javadocJar(type: Jar, dependsOn: javadoc) { task sourcesJar(type: Jar) { from sourceSets.main.allSource classifier = 'sources' +} + +artifacts { + archives jar + + archives javadocJar + archives sourcesJar +} + +signing { + sign configurations.archives +} + +uploadArchives { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2") { + authentication( + userName: sonatypeUsername, + password: sonatypePassword + ) + } + + pom.project { + name 'Mockito-Kotlin' + packaging 'jar' + description 'Using Mockito with Kotlin.' + url 'https://github.com/nhaarman/mockito-kotlin' + + scm { + url 'scm:git@github.com:nhaarman/mockito-kotlin.git' + connection 'scm:git@github.com:nhaarman/mockito-kotlin.git' + developerConnection 'scm:git@github.com:nhaarman/mockito-kotlin.git' + } + + licenses { + license { + name 'MIT' + distribution 'repo' + } + } + + developers { + developer { + id 'nhaarman' + name 'Niek Haarman' + } + } + } + } + } } \ No newline at end of file -- cgit v1.2.3 From fb74552e44d79172beb6acf6275873b3d00c89de Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 21 Oct 2016 22:31:03 +0200 Subject: Use dokka do generate docs --- mockito-kotlin/build.gradle | 15 +++++++++++++++ mockito-kotlin/publishing.gradle | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 9337dde..6ba3e1a 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,15 +1,18 @@ apply plugin: 'kotlin' apply from: './publishing.gradle' +apply plugin: 'org.jetbrains.dokka' buildscript { ext.kotlin_version = '1.0.4' repositories { mavenCentral() + jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.9" } } @@ -48,3 +51,15 @@ dependencies { testCompile "junit:junit:4.12" testCompile "com.nhaarman:expect.kt:0.6.0" } + +dokka { + outputFormat = 'html' + outputDirectory = "$buildDir/javadoc" + + linkMapping { + dir = "src/main/kotlin" + url = "https://github.com/nhaarman/mockito-kotlin/tree/master/mockito-kotlin/src/main/kotlin" + suffix = "#L" + } +} +javadoc.dependsOn dokka \ No newline at end of file diff --git a/mockito-kotlin/publishing.gradle b/mockito-kotlin/publishing.gradle index 3b08ab8..7cc2391 100644 --- a/mockito-kotlin/publishing.gradle +++ b/mockito-kotlin/publishing.gradle @@ -9,7 +9,7 @@ def sonatypePassword = hasProperty('sonatype_password') ? sonatype_password : Sy task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' - from 'build/docs/javadoc' + from 'build/javadoc' } task sourcesJar(type: Jar) { -- cgit v1.2.3 From 3db9e21b9866b77312b53a4ec381cdc10d159cb7 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 21 Oct 2016 22:34:41 +0200 Subject: Update Mockito to 2.2.6 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 6ba3e1a..fd7f967 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -45,7 +45,7 @@ test.dependsOn testInlineMockito dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.2.1" + compile "org.mockito:mockito-core:2.2.6" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 63826bfaf04dbde8895353c11f804d907d92d8c4 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 21 Oct 2016 22:40:17 +0200 Subject: Upgrade deprecation levels to ERROR --- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 4 +-- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 8 ++--- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 36 ---------------------- 3 files changed, 6 insertions(+), 42 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt index dcbbe43..cc25b3b 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt @@ -32,7 +32,7 @@ inline fun argumentCaptor(): KArgumentCaptor = KArgumentCap inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() -@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()")) +@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()"), DeprecationLevel.ERROR) inline fun capture(captor: KArgumentCaptor): T = captor.capture() class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass) { @@ -51,7 +51,7 @@ class KArgumentCaptor(private val captor: ArgumentCaptor, privat * Instead, use [argumentCaptor] in the traditional way, or use one of * [argThat], [argForWhich] or [check]. */ -@Deprecated("Use argumentCaptor() or argThat() instead.") +@Deprecated("Use argumentCaptor() or argThat() instead.", ReplaceWith("check(consumer)"), DeprecationLevel.ERROR) inline fun capture(noinline consumer: (T) -> Unit): T { var times = 0 return argThat { if (++times == 1) consumer.invoke(this); true } diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index dc6e67b..86fc85d 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -130,14 +130,14 @@ fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(* fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! fun withSettings(): MockSettings = Mockito.withSettings()!! -@Deprecated("Use any() instead.", ReplaceWith("any()")) +@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) inline fun anyCollection(): Collection = any() -@Deprecated("Use any() instead.", ReplaceWith("any()")) +@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) inline fun anyList(): List = any() -@Deprecated("Use any() instead.", ReplaceWith("any()")) +@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) inline fun anySet(): Set = any() -@Deprecated("Use any() instead.", ReplaceWith("any()")) +@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) inline fun anyMap(): Map = any() diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 897e0d3..723cb37 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -73,42 +73,6 @@ class MockitoTest { } } - @Test - fun anyCollectionOfClosed() { - mock().apply { - closedCollection(listOf()) - verify(this).closedCollection(any()) - verify(this).closedCollection(anyCollection()) - } - } - - @Test - fun anyListOfClosed() { - mock().apply { - closedList(listOf()) - verify(this).closedList(any()) - verify(this).closedList(anyList()) - } - } - - @Test - fun anyClosedStringMap() { - mock().apply { - closedStringMap(mapOf()) - verify(this).closedStringMap(any()) - verify(this).closedStringMap(anyMap()) - } - } - - @Test - fun anyClosedSet() { - mock().apply { - closedSet(setOf()) - verify(this).closedSet(any()) - verify(this).closedSet(anySet()) - } - } - @Test fun anyStringVararg() { mock().apply { -- cgit v1.2.3 From 6126454769bcb9db9b3ef00038ceb283e9cdd607 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 21 Oct 2016 22:52:28 +0200 Subject: Update version badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a951f2..339bf37 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Mockito-Kotlin -[ ![Download](https://api.bintray.com/packages/nhaarman/maven/Mockito-Kotlin/images/download.svg) ](https://bintray.com/nhaarman/maven/Mockito-Kotlin/_latestVersion) +[ ![Download](https://maven-badges.herokuapp.com/maven-central/com.nhaarman/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/com.nhaarman/mockito-kotlin) A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. -- cgit v1.2.3 From 395e578747cf4fe53af85ad377cb9d4e9ad8ab47 Mon Sep 17 00:00:00 2001 From: desilvai Date: Fri, 21 Oct 2016 14:11:54 -0500 Subject: Fixed infinite loop caused by 'copy constructors' invoked by createInstance. The fix is to skip all constructors that take in parameters with same type as the object we are trying to build. --- mockito-kotlin/build.gradle | 2 +- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 14 +++++++++- .../src/test/kotlin/CreateInstanceTest.kt | 31 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index fd7f967..7d7c4c8 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -62,4 +62,4 @@ dokka { suffix = "#L" } } -javadoc.dependsOn dokka \ No newline at end of file +javadoc.dependsOn dokka diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 07bf704..f38ea90 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -85,14 +85,26 @@ fun createInstance(kClass: KClass): T { private fun KClass.easiestConstructor(): KFunction { return constructors .sortedBy { it.parameters.size } + .withoutParametersOfType(this.defaultType) .withoutArrayParameters() - .firstOrNull() ?: constructors.sortedBy { it.parameters.size }.first() + .firstOrNull() ?: constructors.sortedBy { it.parameters.size } + .withoutParametersOfType(this.defaultType) + .first() } private fun List>.withoutArrayParameters() = filter { it.parameters.filter { parameter -> parameter.type.toString().toLowerCase().contains("array") }.isEmpty() } +/** + * Filters out functions with the given type. + * This is especially useful to avoid infinite loops where constructors + * accepting a parameter of their own type, e.g. 'copy constructors'. + */ +private fun List>.withoutParametersOfType(type: KType) = filter { + it.parameters.filter { it.type == type }.isEmpty() +} + @Suppress("SENSELESS_COMPARISON") private fun KClass<*>.hasObjectInstance() = objectInstance != null diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index 1cae9ff..a643a50 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -436,6 +436,27 @@ class CreateInstanceTest { expect(result).toNotBeNull() } + /** + * Bug: When the copy constructor is selected, we end up with an infinite + * loop. Instead, we want to select a constructor that doesn't + * take in a parameter with the same type as the one we are building. + * + * GIVEN a class with a copy constructor (in the case of the bug, the copy + * constructor has to be selected, so it must have fewer parameters + * than all other constructors) + * WHEN we make an instance of the given class + * THEN we expect that the new, non-null instance will be created without + * an exception + */ + @Test + fun copyConstructorDoesNotCauseException() { + /* When */ + val result = createInstance(WithCopyConstructor::class) + + /* Then */ + expect(result).toNotBeNull() + } + private class PrivateClass private constructor(val data: String) class ClosedClass @@ -475,5 +496,15 @@ class CreateInstanceTest { constructor(c: ForbiddenConstructor) : this() } + /** + * Bug: When the copy constructor is selected, then create instance gets + * into an infinite loop. We should never use the copy constructor in + * createInstance. + */ + data class WithCopyConstructor private constructor(val x: String, + val y: String) { + constructor(other: WithCopyConstructor): this(other.x, other.y) + } + enum class MyEnum { VALUE, ANOTHER_VALUE } } -- cgit v1.2.3 From 086d482907696e713cd29cd399e8b16ad3b730d1 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 26 Oct 2016 11:19:23 +0200 Subject: Add `nullableArgumentCaptor` to be able to work with lists of nullables --- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 8 ++-- .../src/test/kotlin/ArgumentCaptorTest.kt | 50 +++++++++++++++++++--- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt index cc25b3b..a759da4 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt @@ -29,13 +29,14 @@ import org.mockito.ArgumentCaptor import kotlin.reflect.KClass inline fun argumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) +inline fun nullableArgumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() @Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()"), DeprecationLevel.ERROR) inline fun capture(captor: KArgumentCaptor): T = captor.capture() -class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass) { +class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass<*>) { val value: T get() = captor.value @@ -43,7 +44,8 @@ class KArgumentCaptor(private val captor: ArgumentCaptor, privat val allValues: List get() = captor.allValues - fun capture(): T = captor.capture() ?: createInstance(tClass) + @Suppress("UNCHECKED_CAST") + fun capture(): T = captor.capture() ?: createInstance(tClass) as T } /** @@ -51,7 +53,7 @@ class KArgumentCaptor(private val captor: ArgumentCaptor, privat * 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 capture(noinline consumer: (T) -> Unit): T { var times = 0 return argThat { if (++times == 1) consumer.invoke(this); true } diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt index 5a176dc..54aefbd 100644 --- a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt +++ b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt @@ -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() @@ -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() + 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() + verify(m).nullableString(captor.capture()) + expect(captor.value).toBeNull() + } + @Test fun argumentCaptor_multipleValues() { /* Given */ @@ -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() + verify(m, times(2)).nullableString(captor.capture()) + expect(captor.allValues).toBe(listOf("test", null)) + } } \ No newline at end of file -- cgit v1.2.3 From 42cee20efbefd6405000cc25444355990e66834f Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 26 Oct 2016 12:06:27 +0200 Subject: Don't count optional parameters when trying to find an easy constructor --- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 19 ++++++------- .../src/test/kotlin/CreateInstanceTest.kt | 32 +++++++++++++++++++++- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index f38ea90..cab7694 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -34,10 +34,7 @@ import java.lang.reflect.InvocationTargetException import java.lang.reflect.Modifier import java.lang.reflect.ParameterizedType import java.lang.reflect.Type -import kotlin.reflect.KClass -import kotlin.reflect.KFunction -import kotlin.reflect.KType -import kotlin.reflect.defaultType +import kotlin.reflect.* import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaType import kotlin.reflect.jvm.jvmName @@ -84,12 +81,12 @@ fun createInstance(kClass: KClass): T { */ private fun KClass.easiestConstructor(): KFunction { return constructors - .sortedBy { it.parameters.size } + .sortedBy { it.parameters.withoutOptionalParameters().size } .withoutParametersOfType(this.defaultType) .withoutArrayParameters() - .firstOrNull() ?: constructors.sortedBy { it.parameters.size } - .withoutParametersOfType(this.defaultType) - .first() + .firstOrNull() ?: constructors.sortedBy { it.parameters.withoutOptionalParameters().size } + .withoutParametersOfType(this.defaultType) + .first() } private fun List>.withoutArrayParameters() = filter { @@ -101,10 +98,12 @@ private fun List>.withoutArrayParameters() = filter { * This is especially useful to avoid infinite loops where constructors * accepting a parameter of their own type, e.g. 'copy constructors'. */ -private fun List>.withoutParametersOfType(type: KType) = filter { +private fun List>.withoutParametersOfType(type: KType) = filter { it.parameters.filter { it.type == type }.isEmpty() } +private fun List.withoutOptionalParameters() = filterNot { it.isOptional } + @Suppress("SENSELESS_COMPARISON") private fun KClass<*>.hasObjectInstance() = objectInstance != null @@ -166,7 +165,7 @@ private fun KClass.toClassObject(): T { private fun KFunction.newInstance(): T { try { isAccessible = true - return callBy(parameters.associate { + return callBy(parameters.withoutOptionalParameters().associate { it to it.type.createNullableInstance() }) } catch(e: InvocationTargetException) { diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index a643a50..991bf73 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -457,6 +457,25 @@ class CreateInstanceTest { expect(result).toNotBeNull() } + @Test + fun optionalParametersAreSkippedWhenSorting() { + /* When */ + val result = createInstance(WithDefaultParameters::class) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun defaultValuesAreUsedWithOptionalParameters() { + /* When */ + val result = createInstance(WithDefaultParameters::class) + + /* Then */ + expect(result.first).toBe(1) + expect(result.second).toBe(2) + } + private class PrivateClass private constructor(val data: String) class ClosedClass @@ -503,7 +522,18 @@ class CreateInstanceTest { */ data class WithCopyConstructor private constructor(val x: String, val y: String) { - constructor(other: WithCopyConstructor): this(other.x, other.y) + constructor(other: WithCopyConstructor) : this(other.x, other.y) + } + + /** + * A class that uses default parameters, but with a constructor without parameters that fails. + * This is to make sure default parameters are not counted when sorting by parameter size. + */ + class WithDefaultParameters constructor(val first: Int = 1, val second: Int = 2) { + + constructor(first: Int) : this() { + error("Should not be called") + } } enum class MyEnum { VALUE, ANOTHER_VALUE } -- cgit v1.2.3 From 6af0904dcc038ddd48b247b2cc2dafec7e4be0d4 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 26 Oct 2016 12:25:23 +0200 Subject: Update Mockito to 2.2.9 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 7d7c4c8..033dea4 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -45,7 +45,7 @@ test.dependsOn testInlineMockito dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.2.6" + compile "org.mockito:mockito-core:2.2.9" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 113d9e93321b583fcce660af94d1191796d63abb Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 29 Oct 2016 23:37:40 +0200 Subject: Catch an NPE thrown by the Kotlin type checker in the Mockito library. --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 19 ++++++++++++++++++- mockito-kotlin/src/test/kotlin/Classes.kt | 6 +++++- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 11 +++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 86fc85d..0b32699 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -93,7 +93,24 @@ inline fun mock(stubbing: KStubbing.(T) -> Unit): T { class KStubbing(private val mock: T) { fun on(methodCall: R) = Mockito.`when`(methodCall) - fun on(methodCall: T.() -> R) = Mockito.`when`(mock.methodCall()) + + fun on(methodCall: T.() -> R, c: KClass): OngoingStubbing { + val r = try { + mock.methodCall() + } catch(e: NullPointerException) { + // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a + // null value for a non-nullable generic type. + // We catch this NPE to return a valid instance. + // The Mockito state has already been modified at this point to reflect + // the wanted changes. + createInstance(c) + } + return Mockito.`when`(r) + } + + inline fun on(noinline methodCall: T.() -> R): OngoingStubbing { + return on(methodCall, R::class) + } } infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing = thenReturn(t) diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index 979c71b..faa6745 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -54,7 +54,11 @@ interface Methods { fun nullableString(s: String?) fun stringResult(): String - fun builderMethod() : Methods + fun builderMethod(): Methods +} + +interface GenericMethods { + fun genericMethod(): T } class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 723cb37..3db6f1b 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -436,4 +436,15 @@ class MockitoTest { expect(mock.stringResult()).toBe("a") expect(mock.stringResult()).toBe("b") } + + @Test + fun doReturn_withGenericIntReturnType() { + /* Given */ + val mock = mock> { + on { genericMethod() } doReturn 2 + } + + /* Then */ + expect(mock.genericMethod()).toBe(2) + } } -- cgit v1.2.3 From 0615231e0a7851ff57fec5ba5b409096c3e82f81 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 3 Nov 2016 11:44:49 +0100 Subject: Don't try to mock primitive/wrapper instances --- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 2 +- .../kotlin/CreateInstanceInlineTest.kt | 124 +++++++++++++++++++++ .../kotlin/CreateInstanceOfImmutableTest.kt | 106 ------------------ 3 files changed, 125 insertions(+), 107 deletions(-) create mode 100644 mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt delete mode 100644 mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index cab7694..72ceb6a 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -67,8 +67,8 @@ fun createInstance(kClass: KClass): T { return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?: when { kClass.hasObjectInstance() -> kClass.objectInstance!! - kClass.isMockable() -> kClass.java.uncheckedMock() kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() + kClass.isMockable() -> kClass.java.uncheckedMock() kClass.isEnum() -> kClass.java.enumConstants.first() kClass.isArray() -> kClass.toArrayInstance() kClass.isClassObject() -> kClass.toClassObject() diff --git a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt new file mode 100644 index 0000000..47e3521 --- /dev/null +++ b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt @@ -0,0 +1,124 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Ian J. De Silva + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.* +import org.junit.Test +import java.io.IOException +import java.math.BigInteger + +class CreateInstanceInlineTest { + + class ClassToBeMocked { + + fun doSomething(c: ClassToBeMocked) { + } + + fun doSomethingElse(value: BigInteger): BigInteger { + return value.plus(BigInteger.ONE) + } + } + + @Test + fun mockClosedClass() { + /* When */ + val result = mock() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass() { + /* Given */ + val mock = mock() + + /* When */ + mock.doSomething(mock) + + /* Then */ + verify(mock).doSomething(any()) + } + + @Test + fun mockClosedFunction_mockStubbing() { + /* Given */ + val mock = mock { + on { doSomethingElse(any()) } doReturn (BigInteger.ONE) + } + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + @Test + fun mockClosedFunction_whenever() { + /* Given */ + val mock = mock() + whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ + @Test + fun anyThrowableWithSingleThrowableConstructor() { + mock().apply { + throwableClass(ThrowableClass(IOException())) + verify(this).throwableClass(any()) + } + } + + @Test + fun createPrimitiveInstance() { + /* When */ + val i = createInstance() + + /* Then */ + expect(i).toBe(0) + } + + @Test + fun createStringInstance() { + /* When */ + val s = createInstance() + + /* Then */ + expect(s).toBe("") + } + + interface Methods { + + fun throwableClass(t: ThrowableClass) + } + + class ThrowableClass(cause: Throwable) : Throwable(cause) +} diff --git a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt deleted file mode 100644 index a5abaf8..0000000 --- a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceOfImmutableTest.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Ian J. De Silva - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* -import org.junit.Test -import java.io.IOException -import java.math.BigInteger - -class CreateInstanceOfImmutableTest { - - class ClassToBeMocked { - - fun doSomething(c: ClassToBeMocked) { - } - - fun doSomethingElse(value: BigInteger): BigInteger { - return value.plus(BigInteger.ONE) - } - } - - @Test - fun mockClosedClass() { - /* When */ - val result = mock() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyClosedClass() { - /* Given */ - val mock = mock() - - /* When */ - mock.doSomething(mock) - - /* Then */ - verify(mock).doSomething(any()) - } - - @Test - fun mockClosedFunction_mockStubbing() { - /* Given */ - val mock = mock { - on { doSomethingElse(any()) } doReturn (BigInteger.ONE) - } - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - @Test - fun mockClosedFunction_whenever() { - /* Given */ - val mock = mock() - whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ - @Test - fun anyThrowableWithSingleThrowableConstructor() { - mock().apply { - throwableClass(ThrowableClass(IOException())) - verify(this).throwableClass(any()) - } - } - - interface Methods { - - fun throwableClass(t: ThrowableClass) - } - - class ThrowableClass(cause: Throwable) : Throwable(cause) -} -- cgit v1.2.3 From f353562101d9cdfbe5fea642d12b1a590aac2f73 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 3 Nov 2016 12:25:03 +0100 Subject: Accept nullable return types when stubbing --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 14 +++++++--- mockito-kotlin/src/test/kotlin/Classes.kt | 1 + mockito-kotlin/src/test/kotlin/MockitoTest.kt | 30 ++++++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 0b32699..fc69825 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -94,7 +94,7 @@ inline fun mock(stubbing: KStubbing.(T) -> Unit): T { class KStubbing(private val mock: T) { fun on(methodCall: R) = Mockito.`when`(methodCall) - fun on(methodCall: T.() -> R, c: KClass): OngoingStubbing { + fun onGeneric(methodCall: T.() -> R, c: KClass): OngoingStubbing { val r = try { mock.methodCall() } catch(e: NullPointerException) { @@ -108,8 +108,16 @@ class KStubbing(private val mock: T) { return Mockito.`when`(r) } - inline fun on(noinline methodCall: T.() -> R): OngoingStubbing { - return on(methodCall, R::class) + inline fun onGeneric(noinline methodCall: T.() -> R): OngoingStubbing { + return onGeneric(methodCall, R::class) + } + + fun on(methodCall: T.() -> R): OngoingStubbing { + return try { + Mockito.`when`(mock.methodCall()) + } catch(e: NullPointerException) { + throw MockitoKotlinException("NullPointerException thrown when stubbing. If you are trying to stub a generic method, try `onGeneric` instead.", e) + } } } diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index faa6745..7192300 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -54,6 +54,7 @@ interface Methods { fun nullableString(s: String?) fun stringResult(): String + fun nullableStringResult(): String? fun builderMethod(): Methods } diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index 3db6f1b..b32355f 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -351,6 +351,20 @@ class MockitoTest { expect(result).toBeTheSameAs(mock) } + @Test + fun testMockStubbing_nullable() { + /* Given */ + val mock = mock { + on { nullableStringResult() } doReturn "Test" + } + + /* When */ + val result = mock.nullableStringResult() + + /* Then */ + expect(result).toBe("Test") + } + @Test fun testMockStubbing_doThrow() { /* Given */ @@ -438,10 +452,22 @@ class MockitoTest { } @Test - fun doReturn_withGenericIntReturnType() { + fun doReturn_withGenericIntReturnType_on() { + /* Expect */ + expectErrorWithMessage("onGeneric") on { + + /* When */ + mock> { + on { genericMethod() } doReturn 2 + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_onGeneric() { /* Given */ val mock = mock> { - on { genericMethod() } doReturn 2 + onGeneric { genericMethod() } doReturn 2 } /* Then */ -- cgit v1.2.3 From c8fecf02ab38ae3effa06309ddeed1be0b933395 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 3 Nov 2016 12:43:06 +0100 Subject: Try to use constructor when mocking fails --- .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 32 ++++++++++++++++------ .../src/test/kotlin/CreateInstanceTest.kt | 22 +++++++++++++++ .../kotlin/CreateInstanceInlineTest.kt | 26 +++++++++++++++++- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 72ceb6a..4897ec2 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -64,15 +64,31 @@ inline fun createInstance() = createInstance(T::class) @Suppress("UNCHECKED_CAST") fun createInstance(kClass: KClass): T { + var cause: Throwable? = null return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?: - when { - kClass.hasObjectInstance() -> kClass.objectInstance!! - kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() - kClass.isMockable() -> kClass.java.uncheckedMock() - kClass.isEnum() -> kClass.java.enumConstants.first() - kClass.isArray() -> kClass.toArrayInstance() - kClass.isClassObject() -> kClass.toClassObject() - else -> kClass.easiestConstructor().newInstance() + try { + when { + kClass.hasObjectInstance() -> kClass.objectInstance!! + kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() + kClass.isEnum() -> kClass.java.enumConstants.first() + kClass.isArray() -> kClass.toArrayInstance() + kClass.isClassObject() -> kClass.toClassObject() + kClass.isMockable() -> try { + kClass.java.uncheckedMock() + } catch(e: Throwable) { + cause = e + kClass.easiestConstructor().newInstance() + } + else -> kClass.easiestConstructor().newInstance() + } + } catch(e: Exception) { + if (e is MockitoKotlinException) throw e + + cause?.let { + @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") + (e as java.lang.Throwable).initCause(it) + } + throw MockitoKotlinException("Could not create an instance for $kClass.", e) } } diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index 991bf73..2fc7e65 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -476,6 +476,24 @@ class CreateInstanceTest { expect(result.second).toBe(2) } + @Test + fun sealedClass() { + /* When */ + val result = createInstance(MySealedClass::class) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun sealedClassMember() { + /* When */ + val result = createInstance(MySealedClass.MySealedClassMember::class) + + /* Then */ + expect(result).toNotBeNull() + } + private class PrivateClass private constructor(val data: String) class ClosedClass @@ -537,4 +555,8 @@ class CreateInstanceTest { } enum class MyEnum { VALUE, ANOTHER_VALUE } + + sealed class MySealedClass { + class MySealedClassMember : MySealedClass() + } } diff --git a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt index 47e3521..e7cf038 100644 --- a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt +++ b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt @@ -23,6 +23,7 @@ */ import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.mockito_kotlin.* import org.junit.Test import java.io.IOException @@ -105,7 +106,7 @@ class CreateInstanceInlineTest { /* Then */ expect(i).toBe(0) } - + @Test fun createStringInstance() { /* When */ @@ -115,10 +116,33 @@ class CreateInstanceInlineTest { expect(s).toBe("") } + @Test + fun sealedClass_fails() { + /* Expect */ + expectErrorWithMessage("Could not create") on { + + /* When */ + createInstance(MySealedClass::class) + } + } + + @Test + fun sealedClassMember() { + /* When */ + val result = createInstance(MySealedClass.MySealedClassMember::class) + + /* Then */ + expect(result).toNotBeNull() + } + interface Methods { fun throwableClass(t: ThrowableClass) } class ThrowableClass(cause: Throwable) : Throwable(cause) + + sealed class MySealedClass { + class MySealedClassMember : MySealedClass() + } } -- cgit v1.2.3 From e7ed7cb803ca672a738415507f18ef8e3babb6d4 Mon Sep 17 00:00:00 2001 From: rongi Date: Wed, 9 Nov 2016 10:40:38 +0100 Subject: Update to Kotlin 1.0.5 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 033dea4..83afcb5 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: './publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = '1.0.4' + ext.kotlin_version = '1.0.5' repositories { mavenCentral() -- cgit v1.2.3 From a8316570bc5064df51b9d073c554ff17bc7ea2f2 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 12 Nov 2016 14:16:46 +0100 Subject: Update Mockito to 2.2.15 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 83afcb5..2403773 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -45,7 +45,7 @@ test.dependsOn testInlineMockito dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.2.9" + compile "org.mockito:mockito-core:2.2.15" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 1eead3ea7f868e727b606afaf052ea2827119096 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 12 Nov 2016 14:24:33 +0100 Subject: Return passed value instead of trying to create an instance This also enables a nullable value to be passed to eq(). --- .../src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 4 ++-- mockito-kotlin/src/test/kotlin/EqTest.kt | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index fc69825..cad5d13 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -72,7 +72,7 @@ fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber = Mocki fun doThrow(toBeThrown: KClass): Stubber = Mockito.doThrow(toBeThrown.java)!! fun doThrow(vararg toBeThrown: Throwable): Stubber = Mockito.doThrow(*toBeThrown)!! -inline fun eq(value: T): T = Mockito.eq(value) ?: createInstance() +fun eq(value: T): T = Mockito.eq(value) ?: value fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks)!! fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! @@ -138,7 +138,7 @@ fun refEq(value: T, vararg excludeFields: String): T? = Mockito.refEq(value, fun reset(vararg mocks: T) = Mockito.reset(*mocks) -fun same(value: T): T? = Mockito.same(value) +fun same(value: T): T? = Mockito.same(value) ?: value inline fun spy(): T = Mockito.spy(T::class.java)!! fun spy(value: T): T = Mockito.spy(value)!! diff --git a/mockito-kotlin/src/test/kotlin/EqTest.kt b/mockito-kotlin/src/test/kotlin/EqTest.kt index 3e4294d..3c27cf0 100644 --- a/mockito-kotlin/src/test/kotlin/EqTest.kt +++ b/mockito-kotlin/src/test/kotlin/EqTest.kt @@ -78,6 +78,18 @@ class EqTest { expect(result).toNotBeNull() } + @Test + fun nullArgument() { + /* Given */ + val s: String? = null + + /* When */ + val result = eq(s) + + /* Then */ + expect(result).toBeNull() + } + private interface MyInterface private open class MyClass : MyInterface class ClosedClass -- cgit v1.2.3 From 81a0996976039f79817ffb5ee29ba244b08209f5 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 12 Nov 2016 14:38:43 +0100 Subject: Add value shortcuts to ArgumentCaptor This enables easy access to the first, second, third and last called argument value. --- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 48 ++++++++++++++++++++-- .../src/test/kotlin/ArgumentCaptorTest.kt | 47 +++++++++++++++++++-- mockito-kotlin/src/test/kotlin/Classes.kt | 1 + .../src/test/kotlin/CreateInstanceTest.kt | 6 +-- .../kotlin/CreateInstanceInlineTest.kt | 2 +- 5 files changed, 93 insertions(+), 11 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt index a759da4..f93a5eb 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt @@ -33,14 +33,40 @@ inline fun nullableArgumentCaptor(): KArgumentCaptor = KAr inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() -@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()"), DeprecationLevel.ERROR) -inline fun capture(captor: KArgumentCaptor): T = captor.capture() - class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass<*>) { + @Deprecated("Use lastValue", ReplaceWith("lastValue")) val value: T get() = captor.value + /** + * The first captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val firstValue: T + get() = captor.firstValue + + /** + * The second captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val secondValue: T + get() = captor.secondValue + + /** + * The third captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val thirdValue: T + get() = captor.thirdValue + + /** + * The last captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val lastValue: T + get() = captor.lastValue + val allValues: List get() = captor.allValues @@ -48,6 +74,18 @@ class KArgumentCaptor(private val captor: ArgumentCaptor, priva fun capture(): T = captor.capture() ?: createInstance(tClass) as T } +val ArgumentCaptor.firstValue: T + get() = allValues[0] + +val ArgumentCaptor.secondValue: T + get() = allValues[1] + +val ArgumentCaptor.thirdValue: T + get() = allValues[2] + +val ArgumentCaptor.lastValue: T + get() = allValues.last() + /** * This method is deprecated because its behavior differs from the Java behavior. * Instead, use [argumentCaptor] in the traditional way, or use one of @@ -58,3 +96,7 @@ inline fun capture(noinline consumer: (T) -> Unit): T { var times = 0 return argThat { if (++times == 1) consumer.invoke(this); true } } + +@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()"), DeprecationLevel.ERROR) +inline fun capture(captor: KArgumentCaptor): T = captor.capture() + diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt index 54aefbd..6e270f2 100644 --- a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt +++ b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt @@ -16,7 +16,7 @@ class ArgumentCaptorTest { /* Then */ val captor = argumentCaptor() verify(date).time = captor.capture() - expect(captor.value).toBe(5L) + expect(captor.lastValue).toBe(5L) } @Test @@ -30,7 +30,7 @@ class ArgumentCaptorTest { /* Then */ val captor = argumentCaptor() verify(m).nullableString(captor.capture()) - expect(captor.value).toBeNull() + expect(captor.lastValue).toBeNull() } @Test @@ -44,7 +44,7 @@ class ArgumentCaptorTest { /* Then */ val captor = nullableArgumentCaptor() verify(m).nullableString(captor.capture()) - expect(captor.value).toBeNull() + expect(captor.lastValue).toBeNull() } @Test @@ -76,4 +76,43 @@ class ArgumentCaptorTest { verify(m, times(2)).nullableString(captor.capture()) expect(captor.allValues).toBe(listOf("test", null)) } -} \ No newline at end of file + + @Test + fun argumentCaptor_callProperties() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.int(1) + m.int(2) + m.int(3) + m.int(4) + m.int(5) + + /* Then */ + argumentCaptor().apply { + verify(m, times(5)).int(capture()) + + expect(firstValue).toBe(1) + expect(secondValue).toBe(2) + expect(thirdValue).toBe(3) + expect(lastValue).toBe(5) + } + } + + @Test(expected = IndexOutOfBoundsException::class) + fun argumentCaptor_callPropertyNotAvailable() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.int(1) + + /* Then */ + argumentCaptor().apply { + verify(m).int(capture()) + + expect(secondValue).toBe(2) + } + } +} diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt index 7192300..0657a94 100644 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/Classes.kt @@ -49,6 +49,7 @@ interface Methods { fun closedStringMap(m: Map) fun closedSet(s: Set) fun string(s: String) + fun int(i: Int) fun closedVararg(vararg c: Closed) fun throwableClass(t: ThrowableClass) fun nullableString(s: String?) diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index 2fc7e65..d91516b 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -525,12 +525,12 @@ class CreateInstanceTest { throw AssertionError("Forbidden.") } - constructor(value: Int) { + constructor(@Suppress("UNUSED_PARAMETER") value: Int) { } } class WithDefaultEmptyConstructor() { - constructor(c: ForbiddenConstructor) : this() + constructor(@Suppress("UNUSED_PARAMETER") c: ForbiddenConstructor) : this() } /** @@ -549,7 +549,7 @@ class CreateInstanceTest { */ class WithDefaultParameters constructor(val first: Int = 1, val second: Int = 2) { - constructor(first: Int) : this() { + constructor(@Suppress("UNUSED_PARAMETER") first: Int) : this() { error("Should not be called") } } diff --git a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt index e7cf038..3d8357b 100644 --- a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt +++ b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt @@ -33,7 +33,7 @@ class CreateInstanceInlineTest { class ClassToBeMocked { - fun doSomething(c: ClassToBeMocked) { + fun doSomething(@Suppress("UNUSED_PARAMETER") c: ClassToBeMocked) { } fun doSomethingElse(value: BigInteger): BigInteger { -- cgit v1.2.3 From ab1eb0dc26d428b916b874eacd7f98660e3c5b18 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 12 Nov 2016 17:31:54 +0100 Subject: Use same test source for inline tests --- .travis.yml | 5 + build.gradle | 2 + gradle.properties | 1 + mockito-kotlin/build.gradle | 44 +++--- mockito-kotlin/publishing.gradle | 2 + .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 4 +- .../src/test/kotlin/ArgumentCaptorTest.kt | 2 +- mockito-kotlin/src/test/kotlin/BaseTest.kt | 16 +++ .../src/test/kotlin/CreateInstanceTest.kt | 8 +- mockito-kotlin/src/test/kotlin/EqTest.kt | 10 +- mockito-kotlin/src/test/kotlin/MockTest.kt | 9 +- .../src/test/kotlin/MockitoKotlinTest.kt | 2 +- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 6 +- mockito-kotlin/src/test/kotlin/SpyTest.kt | 12 +- .../test/kotlin/inline/UsingMockMakerInlineTest.kt | 156 +++++++++++++++++++++ .../kotlin/CreateInstanceInlineTest.kt | 148 ------------------- .../org.mockito.plugins.MockMaker | 1 - 17 files changed, 229 insertions(+), 199 deletions(-) create mode 100644 mockito-kotlin/src/test/kotlin/BaseTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt delete mode 100644 mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt delete mode 100644 mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/.travis.yml b/.travis.yml index 608fe0f..4508f2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,11 @@ language: java jdk: - oraclejdk7 +matrix: + include: + - jdk: oraclejdk7 + env: TERM=dumb MOCK_MAKER=mock-maker-inline + env: matrix: - TERM=dumb diff --git a/build.gradle b/build.gradle index dae319a..4bda747 100644 --- a/build.gradle +++ b/build.gradle @@ -3,3 +3,5 @@ plugins { } apply from: 'gradle/scripts/tagging.gradle' + +println ext.versionName \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 278ac4e..92fd338 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,3 +24,4 @@ # isRelease = false +publishToLocal = false diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 2403773..32c06da 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -21,27 +21,6 @@ repositories { jcenter() } -sourceSets { - testInlineMockito { - compileClasspath += main.output + test.output - runtimeClasspath += main.output + test.output - } -} - -configurations { - testInlineMockitoCompile.extendsFrom testCompile - testInlineMockitoRuntime.extendsFrom testRuntime -} - -// define custom test task for running integration tests -task testInlineMockito(type: Test) { - testClassesDir = sourceSets.testInlineMockito.output.classesDir - classpath = sourceSets.testInlineMockito.runtimeClasspath -} - -test.dependsOn testInlineMockito - - dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" @@ -63,3 +42,26 @@ dokka { } } javadoc.dependsOn dokka + +//Switch inline +task createTestResources << { + def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") + if (System.env.MOCK_MAKER != null) { + logger.warn("! Using MockMaker ${System.env.MOCK_MAKER}") + mockMakerFile.parentFile.mkdirs() + mockMakerFile.createNewFile() + mockMakerFile.write(System.env.MOCK_MAKER) + } else { + logger.warn("! Using default MockMaker") + } +} + +task removeTestResources << { + def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") + if (mockMakerFile.exists()) { + mockMakerFile.delete() + } +} + +test.dependsOn createTestResources +test.finalizedBy removeTestResources diff --git a/mockito-kotlin/publishing.gradle b/mockito-kotlin/publishing.gradle index 7cc2391..33f60f3 100644 --- a/mockito-kotlin/publishing.gradle +++ b/mockito-kotlin/publishing.gradle @@ -40,6 +40,8 @@ uploadArchives { ) } + if (publishToLocal) repository(url: mavenLocal().url) + pom.project { name 'Mockito-Kotlin' packaging 'jar' diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt index 4897ec2..772fdca 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt @@ -48,9 +48,9 @@ import java.lang.reflect.Array as JavaArray /** * Checks whether the resource file to enable mocking of final classes is present. */ -private var mockMakerInlineEnabled: Boolean? = null +internal var mockMakerInlineEnabled: Boolean? = null -private fun mockMakerInlineEnabled(jClass: Class): Boolean { +internal fun mockMakerInlineEnabled(jClass: Class): Boolean { return mockMakerInlineEnabled ?: jClass.getResource("mockito-extensions/org.mockito.plugins.MockMaker")?.let { mockMakerInlineEnabled = File(it.file).readLines().filter { it == "mock-maker-inline" }.isNotEmpty() diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt index 6e270f2..f1986f5 100644 --- a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt +++ b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt @@ -3,7 +3,7 @@ import com.nhaarman.mockito_kotlin.* import org.junit.Test import java.util.* -class ArgumentCaptorTest { +class ArgumentCaptorTest : BaseTest() { @Test fun argumentCaptor_withSingleValue() { diff --git a/mockito-kotlin/src/test/kotlin/BaseTest.kt b/mockito-kotlin/src/test/kotlin/BaseTest.kt new file mode 100644 index 0000000..ba2ef1f --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/BaseTest.kt @@ -0,0 +1,16 @@ +import com.nhaarman.mockito_kotlin.mockMakerInlineEnabled +import org.junit.After +import org.junit.Before + +abstract class BaseTest { + + @Before + open fun setup() { + mockMakerInlineEnabled = false + } + + @After + open fun tearDown() { + mockMakerInlineEnabled = null + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt index d91516b..15f0aaf 100644 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt @@ -31,7 +31,7 @@ import org.junit.Test import java.util.* import kotlin.reflect.KClass -class CreateInstanceTest { +class CreateInstanceTest : BaseTest() { @Test fun byte() { @@ -555,8 +555,8 @@ class CreateInstanceTest { } enum class MyEnum { VALUE, ANOTHER_VALUE } +} - sealed class MySealedClass { - class MySealedClassMember : MySealedClass() - } +sealed class MySealedClass { + class MySealedClassMember : MySealedClass() } diff --git a/mockito-kotlin/src/test/kotlin/EqTest.kt b/mockito-kotlin/src/test/kotlin/EqTest.kt index 3c27cf0..df993bf 100644 --- a/mockito-kotlin/src/test/kotlin/EqTest.kt +++ b/mockito-kotlin/src/test/kotlin/EqTest.kt @@ -31,7 +31,7 @@ import org.junit.Before import org.junit.Test import org.mockito.Mockito -class EqTest { +class EqTest : BaseTest() { private val interfaceInstance: MyInterface = MyClass() private val openClassInstance: MyClass = MyClass() @@ -40,13 +40,17 @@ class EqTest { private lateinit var doAnswer: Open @Before - fun setup() { + override fun setup() { + super.setup() + /* Create a proper Mockito state */ doAnswer = Mockito.doAnswer { }.`when`(mock()) } @After - fun tearDown() { + override fun tearDown() { + super.tearDown() + /* Close `any` Mockito state */ doAnswer.go(0) } diff --git a/mockito-kotlin/src/test/kotlin/MockTest.kt b/mockito-kotlin/src/test/kotlin/MockTest.kt index e46f3db..132c3b7 100644 --- a/mockito-kotlin/src/test/kotlin/MockTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockTest.kt @@ -28,10 +28,9 @@ import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.whenever import org.junit.Test import org.mockito.Mockito.RETURNS_DEEP_STUBS -import org.mockito.exceptions.base.MockitoException import java.util.* -class MockTest { +class MockTest : BaseTest() { private lateinit var propertyInterfaceVariable: MyInterface private lateinit var propertyClassVariable: MyClass @@ -80,11 +79,6 @@ class MockTest { expect(instance).toNotBeNull() } - @Test(expected = MockitoException::class) - fun closedClass() { - mock() - } - @Test fun deepStubs() { val cal: Calendar = mock(RETURNS_DEEP_STUBS) @@ -94,6 +88,5 @@ class MockTest { private interface MyInterface private open class MyClass - private class ClosedClass } diff --git a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt index b0465d1..dceeb41 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt @@ -28,7 +28,7 @@ import com.nhaarman.mockito_kotlin.* import org.junit.After import org.junit.Test -class MockitoKotlinTest { +class MockitoKotlinTest : BaseTest() { @After fun teardown() { diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt index b32355f..41325ff 100644 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/MockitoTest.kt @@ -1,7 +1,9 @@ + import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail import com.nhaarman.mockito_kotlin.* +import org.junit.Assume.assumeTrue import org.junit.Test import org.mockito.exceptions.base.MockitoAssertionError import java.io.IOException @@ -31,7 +33,7 @@ import java.io.IOException * THE SOFTWARE. */ -class MockitoTest { +class MockitoTest : BaseTest() { @Test fun anyString() { @@ -100,6 +102,8 @@ class MockitoTest { /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ @Test fun anyThrowableWithSingleThrowableConstructor() { + assumeTrue(mockMakerInlineEnabled(javaClass)) + mock().apply { throwableClass(ThrowableClass(IOException())) verify(this).throwableClass(any()) diff --git a/mockito-kotlin/src/test/kotlin/SpyTest.kt b/mockito-kotlin/src/test/kotlin/SpyTest.kt index e09ee25..c673b5f 100644 --- a/mockito-kotlin/src/test/kotlin/SpyTest.kt +++ b/mockito-kotlin/src/test/kotlin/SpyTest.kt @@ -31,18 +31,18 @@ import org.mockito.Mockito import org.mockito.exceptions.base.MockitoException import java.util.* -class SpyTest { +class SpyTest : BaseTest() { private val interfaceInstance: MyInterface = MyClass() private val openClassInstance: MyClass = MyClass() private val closedClassInstance: ClosedClass = ClosedClass() @After - fun a() { + override fun tearDown() { + super.tearDown() Mockito.validateMockitoUsage() } - @Test fun spyInterfaceInstance() { /* When */ @@ -61,12 +61,6 @@ class SpyTest { expect(result).toNotBeNull() } - @Test(expected = MockitoException::class) - fun spyClosedClassInstance() { - /* When */ - spy(closedClassInstance) - } - @Test fun doReturnWithSpy() { val date = spy(Date()) diff --git a/mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt new file mode 100644 index 0000000..2fa5ac2 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt @@ -0,0 +1,156 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Ian J. De Silva + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockito_kotlin.* +import org.junit.Assume.assumeTrue +import org.junit.Before +import org.junit.Test +import java.io.IOException +import java.math.BigInteger + +class UsingMockMakerInlineTest { + + class ClassToBeMocked { + + fun doSomething(@Suppress("UNUSED_PARAMETER") c: ClassToBeMocked) { + } + + fun doSomethingElse(value: BigInteger): BigInteger { + return value.plus(BigInteger.ONE) + } + } + + @Before + fun setup() { + mockMakerInlineEnabled = null + assumeTrue(mockMakerInlineEnabled(javaClass)) + } + + @Test + fun mockClosedClass() { + /* When */ + val result = mock() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass() { + /* Given */ + val mock = mock() + + /* When */ + mock.doSomething(mock) + + /* Then */ + verify(mock).doSomething(any()) + } + + @Test + fun mockClosedFunction_mockStubbing() { + /* Given */ + val mock = mock { + on { doSomethingElse(any()) } doReturn (BigInteger.ONE) + } + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + @Test + fun mockClosedFunction_whenever() { + /* Given */ + val mock = mock() + whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ + @Test + fun anyThrowableWithSingleThrowableConstructor() { + mock().apply { + throwableClass(ThrowableClass(IOException())) + verify(this).throwableClass(any()) + } + } + + @Test + fun createPrimitiveInstance() { + /* When */ + val i = createInstance() + + /* Then */ + expect(i).toBe(0) + } + + @Test + fun createStringInstance() { + /* When */ + val s = createInstance() + + /* Then */ + expect(s).toBe("") + } + + @Test + fun sealedClass_fails() { + /* Expect */ + expectErrorWithMessage("Could not create") on { + + /* When */ + createInstance(MySealedClass::class) + } + } + + @Test + fun sealedClassMember() { + /* When */ + val result = createInstance(MySealedClass.MySealedClassMember::class) + + /* Then */ + expect(result).toNotBeNull() + } + + interface Methods { + + fun throwableClass(t: ThrowableClass) + } + + class ThrowableClass(cause: Throwable) : Throwable(cause) + + sealed class MySealedClass { + class MySealedClassMember : MySealedClass() + } +} diff --git a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt b/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt deleted file mode 100644 index 3d8357b..0000000 --- a/mockito-kotlin/src/testInlineMockito/kotlin/CreateInstanceInlineTest.kt +++ /dev/null @@ -1,148 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Ian J. De Silva - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockito_kotlin.* -import org.junit.Test -import java.io.IOException -import java.math.BigInteger - -class CreateInstanceInlineTest { - - class ClassToBeMocked { - - fun doSomething(@Suppress("UNUSED_PARAMETER") c: ClassToBeMocked) { - } - - fun doSomethingElse(value: BigInteger): BigInteger { - return value.plus(BigInteger.ONE) - } - } - - @Test - fun mockClosedClass() { - /* When */ - val result = mock() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyClosedClass() { - /* Given */ - val mock = mock() - - /* When */ - mock.doSomething(mock) - - /* Then */ - verify(mock).doSomething(any()) - } - - @Test - fun mockClosedFunction_mockStubbing() { - /* Given */ - val mock = mock { - on { doSomethingElse(any()) } doReturn (BigInteger.ONE) - } - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - @Test - fun mockClosedFunction_whenever() { - /* Given */ - val mock = mock() - whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ - @Test - fun anyThrowableWithSingleThrowableConstructor() { - mock().apply { - throwableClass(ThrowableClass(IOException())) - verify(this).throwableClass(any()) - } - } - - @Test - fun createPrimitiveInstance() { - /* When */ - val i = createInstance() - - /* Then */ - expect(i).toBe(0) - } - - @Test - fun createStringInstance() { - /* When */ - val s = createInstance() - - /* Then */ - expect(s).toBe("") - } - - @Test - fun sealedClass_fails() { - /* Expect */ - expectErrorWithMessage("Could not create") on { - - /* When */ - createInstance(MySealedClass::class) - } - } - - @Test - fun sealedClassMember() { - /* When */ - val result = createInstance(MySealedClass.MySealedClassMember::class) - - /* Then */ - expect(result).toNotBeNull() - } - - interface Methods { - - fun throwableClass(t: ThrowableClass) - } - - class ThrowableClass(cause: Throwable) : Throwable(cause) - - sealed class MySealedClass { - class MySealedClassMember : MySealedClass() - } -} diff --git a/mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker b/mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9c..0000000 --- a/mockito-kotlin/src/testInlineMockito/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file -- cgit v1.2.3 From 18ed580069cc284b05a144335f97421c003e26fb Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 12 Nov 2016 21:37:50 +0100 Subject: Use `null as T` to create instances The old instance creator is still used as a fallback --- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 1 + .../com/nhaarman/mockito_kotlin/CreateInstance.kt | 225 -------- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 1 + .../createinstance/CreateInstance.kt | 36 ++ .../createinstance/InstanceCreator.kt | 184 ++++++ .../mockito_kotlin/createinstance/MockMaker.kt | 10 + .../createinstance/NonNullProvider.kt | 34 ++ .../mockito_kotlin/createinstance/NullCaster.kt | 18 + .../src/test/kotlin/ArgumentCaptorTest.kt | 118 ---- mockito-kotlin/src/test/kotlin/BaseTest.kt | 16 - mockito-kotlin/src/test/kotlin/Classes.kt | 66 --- .../src/test/kotlin/CreateInstanceTest.kt | 562 ------------------- mockito-kotlin/src/test/kotlin/EqTest.kt | 101 ---- mockito-kotlin/src/test/kotlin/MockTest.kt | 92 --- .../src/test/kotlin/MockitoKotlinTest.kt | 78 --- mockito-kotlin/src/test/kotlin/MockitoTest.kt | 480 ---------------- mockito-kotlin/src/test/kotlin/SpyTest.kt | 98 ---- .../test/kotlin/inline/UsingMockMakerInlineTest.kt | 156 ------ .../src/test/kotlin/test/ArgumentCaptorTest.kt | 120 ++++ mockito-kotlin/src/test/kotlin/test/Classes.kt | 66 +++ mockito-kotlin/src/test/kotlin/test/EqTest.kt | 101 ++++ mockito-kotlin/src/test/kotlin/test/MockTest.kt | 92 +++ mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 477 ++++++++++++++++ mockito-kotlin/src/test/kotlin/test/SpyTest.kt | 98 ++++ mockito-kotlin/src/test/kotlin/test/TestBase.kt | 18 + .../test/createinstance/InstanceCreatorTest.kt | 621 +++++++++++++++++++++ .../test/createinstance/NonNullProviderImplTest.kt | 77 +++ .../kotlin/test/createinstance/NullCasterTest.kt | 33 ++ .../kotlin/test/inline/UsingMockMakerInlineTest.kt | 160 ++++++ 29 files changed, 2147 insertions(+), 1992 deletions(-) delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt delete mode 100644 mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/BaseTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/Classes.kt delete mode 100644 mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/EqTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/MockTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/MockitoTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/SpyTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/Classes.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/EqTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/MockTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/MockitoTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/SpyTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/TestBase.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt index f93a5eb..bbf093d 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt @@ -25,6 +25,7 @@ package com.nhaarman.mockito_kotlin +import com.nhaarman.mockito_kotlin.createinstance.createInstance import org.mockito.ArgumentCaptor import kotlin.reflect.KClass diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt deleted file mode 100644 index 772fdca..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/CreateInstance.kt +++ /dev/null @@ -1,225 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -import org.mockito.Answers -import org.mockito.internal.creation.MockSettingsImpl -import org.mockito.internal.creation.bytebuddy.MockAccess -import org.mockito.internal.util.MockUtil -import java.io.File -import java.lang.reflect.InvocationTargetException -import java.lang.reflect.Modifier -import java.lang.reflect.ParameterizedType -import java.lang.reflect.Type -import kotlin.reflect.* -import kotlin.reflect.jvm.isAccessible -import kotlin.reflect.jvm.javaType -import kotlin.reflect.jvm.jvmName -import java.lang.reflect.Array as JavaArray - -/** - * A collection of functions that tries to create an instance of - * classes to avoid NPE's when using Mockito with Kotlin. - */ - -/** - * Checks whether the resource file to enable mocking of final classes is present. - */ -internal var mockMakerInlineEnabled: Boolean? = null - -internal fun mockMakerInlineEnabled(jClass: Class): Boolean { - return mockMakerInlineEnabled ?: - jClass.getResource("mockito-extensions/org.mockito.plugins.MockMaker")?.let { - mockMakerInlineEnabled = File(it.file).readLines().filter { it == "mock-maker-inline" }.isNotEmpty() - mockMakerInlineEnabled - } ?: false -} - -inline fun createArrayInstance() = arrayOf() - -inline fun createInstance() = createInstance(T::class) - -@Suppress("UNCHECKED_CAST") -fun createInstance(kClass: KClass): T { - var cause: Throwable? = null - return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?: - try { - when { - kClass.hasObjectInstance() -> kClass.objectInstance!! - kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() - kClass.isEnum() -> kClass.java.enumConstants.first() - kClass.isArray() -> kClass.toArrayInstance() - kClass.isClassObject() -> kClass.toClassObject() - kClass.isMockable() -> try { - kClass.java.uncheckedMock() - } catch(e: Throwable) { - cause = e - kClass.easiestConstructor().newInstance() - } - else -> kClass.easiestConstructor().newInstance() - } - } catch(e: Exception) { - if (e is MockitoKotlinException) throw e - - cause?.let { - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") - (e as java.lang.Throwable).initCause(it) - } - throw MockitoKotlinException("Could not create an instance for $kClass.", e) - } -} - -/** - * Tries to find the easiest constructor which it can instantiate. - */ -private fun KClass.easiestConstructor(): KFunction { - return constructors - .sortedBy { it.parameters.withoutOptionalParameters().size } - .withoutParametersOfType(this.defaultType) - .withoutArrayParameters() - .firstOrNull() ?: constructors.sortedBy { it.parameters.withoutOptionalParameters().size } - .withoutParametersOfType(this.defaultType) - .first() -} - -private fun List>.withoutArrayParameters() = filter { - it.parameters.filter { parameter -> parameter.type.toString().toLowerCase().contains("array") }.isEmpty() -} - -/** - * Filters out functions with the given type. - * This is especially useful to avoid infinite loops where constructors - * accepting a parameter of their own type, e.g. 'copy constructors'. - */ -private fun List>.withoutParametersOfType(type: KType) = filter { - it.parameters.filter { it.type == type }.isEmpty() -} - -private fun List.withoutOptionalParameters() = filterNot { it.isOptional } - -@Suppress("SENSELESS_COMPARISON") -private fun KClass<*>.hasObjectInstance() = objectInstance != null - -private fun KClass<*>.isMockable(): Boolean { - return !Modifier.isFinal(java.modifiers) || mockMakerInlineEnabled(java) -} - -private fun KClass<*>.isEnum() = java.isEnum -private fun KClass<*>.isArray() = java.isArray -private fun KClass<*>.isClassObject() = jvmName.equals("java.lang.Class") -private fun KClass<*>.isPrimitive() = - java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf( - "Boolean", - "Byte", - "Short", - "Int", - "Double", - "Float", - "Long", - "String" - ) - -@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") -private fun KClass.toDefaultPrimitiveValue(): T { - return when (simpleName) { - "Boolean" -> true - "Byte" -> 0.toByte() - "Short" -> 0.toShort() - "Int" -> 0 - "Double" -> 0.0 - "Float" -> 0f - "Long" -> 0 - "String" -> "" - else -> throw UnsupportedOperationException("Cannot create default primitive for $simpleName.") - } as T -} - -@Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") -private fun KClass.toArrayInstance(): T { - return when (simpleName) { - "ByteArray" -> byteArrayOf() - "ShortArray" -> shortArrayOf() - "IntArray" -> intArrayOf() - "LongArray" -> longArrayOf() - "DoubleArray" -> doubleArrayOf() - "FloatArray" -> floatArrayOf() - else -> { - val name = java.name.drop(2).dropLast(1) - return JavaArray.newInstance(Class.forName(name), 0) as T - } - } as T -} - -@Suppress("UNCHECKED_CAST") -private fun KClass.toClassObject(): T { - return Class.forName("java.lang.Object") as T -} - -private fun KFunction.newInstance(): T { - try { - isAccessible = true - return callBy(parameters.withoutOptionalParameters().associate { - it to it.type.createNullableInstance() - }) - } catch(e: InvocationTargetException) { - throw MockitoKotlinException( - """ - - Could not create an instance of class ${this.returnType}, because of an error with the following message: - - "${e.cause?.message}" - - Try registering an instance creator yourself, using MockitoKotlin.registerInstanceCreator<${this.returnType}> {...}.""", - e.cause - ) - } -} - -@Suppress("UNCHECKED_CAST") -private fun KType.createNullableInstance(): T? { - if (isMarkedNullable) { - return null - } - - val javaType: Type = javaType - return when (javaType) { - is ParameterizedType -> (javaType.rawType as Class).uncheckedMock() - is Class<*> -> createInstance((javaType as Class).kotlin) - else -> null - } -} - -/** - * Creates a mock instance of given class, without modifying or checking any internal Mockito state. - */ -@Suppress("UNCHECKED_CAST") -fun Class.uncheckedMock(): T { - val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl - val creationSettings = impl.confirm(this) - return MockUtil.createMock(creationSettings).apply { - (this as? MockAccess)?.mockitoInterceptor = null - } -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index cad5d13..bbcce1e 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -25,6 +25,7 @@ package com.nhaarman.mockito_kotlin +import com.nhaarman.mockito_kotlin.createinstance.createInstance import org.mockito.InOrder import org.mockito.MockSettings import org.mockito.MockingDetails diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt new file mode 100644 index 0000000..48b4719 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt @@ -0,0 +1,36 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockito_kotlin.createinstance + +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + + +inline fun createInstance(): T + = createInstance(T::class) + +fun createInstance(kClass: KClass): T + = nonNullProvider().createInstance(kClass) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt new file mode 100644 index 0000000..7a8c5ae --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt @@ -0,0 +1,184 @@ +package com.nhaarman.mockito_kotlin.createinstance + +import com.nhaarman.mockito_kotlin.MockitoKotlin +import com.nhaarman.mockito_kotlin.MockitoKotlinException +import org.mockito.Answers +import org.mockito.internal.creation.MockSettingsImpl +import org.mockito.internal.creation.bytebuddy.MockAccess +import org.mockito.internal.util.MockUtil +import java.lang.reflect.InvocationTargetException +import java.lang.reflect.Modifier +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type +import kotlin.reflect.* +import kotlin.reflect.jvm.isAccessible +import kotlin.reflect.jvm.javaType +import kotlin.reflect.jvm.jvmName +import java.lang.reflect.Array as JavaArray + +internal class InstanceCreator() : NonNullProvider { + + override fun createInstance(kClass: KClass): T { + var cause: Throwable? = null + + @Suppress("UNCHECKED_CAST") + return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?: + try { + when { + kClass.hasObjectInstance() -> kClass.objectInstance!! + kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() + kClass.isEnum() -> kClass.java.enumConstants.first() + kClass.isArray() -> kClass.toArrayInstance() + kClass.isClassObject() -> kClass.toClassObject() + kClass.isMockable() -> try { + kClass.java.uncheckedMock() + } catch(e: Throwable) { + cause = e + kClass.easiestConstructor().newInstance() + } + else -> kClass.easiestConstructor().newInstance() + } + } catch(e: Exception) { + if (e is MockitoKotlinException) throw e + + cause?.let { + @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") + (e as java.lang.Throwable).initCause(it) + } + throw MockitoKotlinException("Could not create an instance for $kClass.", e) + } + } + + /** + * Tries to find the easiest constructor which it can instantiate. + */ + private fun KClass.easiestConstructor(): KFunction { + return constructors + .sortedBy { it.parameters.withoutOptionalParameters().size } + .withoutParametersOfType(this.defaultType) + .withoutArrayParameters() + .firstOrNull() ?: constructors.sortedBy { it.parameters.withoutOptionalParameters().size } + .withoutParametersOfType(this.defaultType) + .first() + } + + private fun List>.withoutArrayParameters() = filter { + it.parameters.filter { parameter -> parameter.type.toString().toLowerCase().contains("array") }.isEmpty() + } + + /** + * Filters out functions with the given type. + * This is especially useful to avoid infinite loops where constructors + * accepting a parameter of their own type, e.g. 'copy constructors'. + */ + private fun List>.withoutParametersOfType(type: KType) = filter { + it.parameters.filter { it.type == type }.isEmpty() + } + + private fun List.withoutOptionalParameters() = filterNot { it.isOptional } + + @Suppress("SENSELESS_COMPARISON") + private fun KClass<*>.hasObjectInstance() = objectInstance != null + + private fun KClass<*>.isMockable(): Boolean { + return !Modifier.isFinal(java.modifiers) || mockMakerInlineEnabled() + } + + private fun KClass<*>.isEnum() = java.isEnum + private fun KClass<*>.isArray() = java.isArray + private fun KClass<*>.isClassObject() = jvmName.equals("java.lang.Class") + private fun KClass<*>.isPrimitive() = + java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf( + "Boolean", + "Byte", + "Short", + "Int", + "Double", + "Float", + "Long", + "String" + ) + + @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") + private fun KClass.toDefaultPrimitiveValue(): T { + return when (simpleName) { + "Boolean" -> true + "Byte" -> 0.toByte() + "Short" -> 0.toShort() + "Int" -> 0 + "Double" -> 0.0 + "Float" -> 0f + "Long" -> 0 + "String" -> "" + else -> throw UnsupportedOperationException("Cannot create default primitive for $simpleName.") + } as T + } + + @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") + private fun KClass.toArrayInstance(): T { + return when (simpleName) { + "ByteArray" -> byteArrayOf() + "ShortArray" -> shortArrayOf() + "IntArray" -> intArrayOf() + "LongArray" -> longArrayOf() + "DoubleArray" -> doubleArrayOf() + "FloatArray" -> floatArrayOf() + else -> { + val name = java.name.drop(2).dropLast(1) + return JavaArray.newInstance(Class.forName(name), 0) as T + } + } as T + } + + @Suppress("UNCHECKED_CAST") + private fun KClass.toClassObject(): T { + return Class.forName("java.lang.Object") as T + } + + private fun KFunction.newInstance(): T { + try { + isAccessible = true + return callBy(parameters.withoutOptionalParameters().associate { + it to it.type.createNullableInstance() + }) + } catch(e: InvocationTargetException) { + throw MockitoKotlinException( + """ + + Could not create an instance of class ${this.returnType}, because of an error with the following message: + + "${e.cause?.message}" + + Try registering an instance creator yourself, using MockitoKotlin.registerInstanceCreator<${this.returnType}> {...}.""", + e.cause + ) + } + } + + @Suppress("UNCHECKED_CAST") + private fun KType.createNullableInstance(): T? { + if (isMarkedNullable) { + return null + } + + val javaType: Type = javaType + return when (javaType) { + is ParameterizedType -> (javaType.rawType as Class).uncheckedMock() + is Class<*> -> createInstance((javaType as Class).kotlin) + else -> null + } + } + + /** + * Creates a mock instance of given class, without modifying or checking any internal Mockito state. + */ + @Suppress("UNCHECKED_CAST") + fun Class.uncheckedMock(): T { + val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl + val creationSettings = impl.confirm(this) + return MockUtil.createMock(creationSettings).apply { + (this as? MockAccess)?.mockitoInterceptor = null + } + } +} + diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt new file mode 100644 index 0000000..bf18518 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt @@ -0,0 +1,10 @@ +package com.nhaarman.mockito_kotlin.createinstance + +import org.mockito.internal.configuration.plugins.Plugins +import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker + +internal var mockMakerInlineEnabled: Boolean? = null +internal fun mockMakerInlineEnabled(): Boolean { + return mockMakerInlineEnabled ?: + Plugins.getMockMaker() is InlineByteBuddyMockMaker +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt new file mode 100644 index 0000000..15cb03e --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt @@ -0,0 +1,34 @@ +package com.nhaarman.mockito_kotlin.createinstance + +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + +interface NonNullProvider { + + fun createInstance(kClass: KClass): T +} + +fun nonNullProvider(): NonNullProvider = NonNullProviderImpl(listOf(NullCaster(), InstanceCreator())) + +internal class NonNullProviderImpl( + private val nonNullProviders: List +) : NonNullProvider { + + override fun createInstance(kClass: KClass): T { + return firstNonErroring( + nonNullProviders.map { { it.createInstance(kClass) } } + ) + } + + private fun firstNonErroring(functions: List<() -> T>): T { + var error: Throwable? = null + functions.forEach { f -> + try { + return f() + } catch(e: Throwable) { + error = e + } + } + throw error ?: IllegalStateException() + } +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt new file mode 100644 index 0000000..6cd38c7 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt @@ -0,0 +1,18 @@ +package com.nhaarman.mockito_kotlin.createinstance + +import kotlin.reflect.KClass + +/** + * Uses a quirk in the bytecode generated by Kotlin + * to cast [null] to a non-null type. + * + * See https://youtrack.jetbrains.com/issue/KT-8135. + */ +internal class NullCaster : NonNullProvider { + + override fun createInstance(kClass: KClass): T { + return castNull() + } + + private fun castNull(): T = null as T +} diff --git a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt deleted file mode 100644 index f1986f5..0000000 --- a/mockito-kotlin/src/test/kotlin/ArgumentCaptorTest.kt +++ /dev/null @@ -1,118 +0,0 @@ -import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* -import org.junit.Test -import java.util.* - -class ArgumentCaptorTest : BaseTest() { - - @Test - fun argumentCaptor_withSingleValue() { - /* Given */ - val date: Date = mock() - - /* When */ - date.time = 5L - - /* Then */ - val captor = argumentCaptor() - verify(date).time = captor.capture() - expect(captor.lastValue).toBe(5L) - } - - @Test - fun argumentCaptor_withNullValue_usingNonNullable() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.nullableString(null) - - /* Then */ - val captor = argumentCaptor() - verify(m).nullableString(captor.capture()) - expect(captor.lastValue).toBeNull() - } - - @Test - fun argumentCaptor_withNullValue_usingNullable() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.nullableString(null) - - /* Then */ - val captor = nullableArgumentCaptor() - verify(m).nullableString(captor.capture()) - expect(captor.lastValue).toBeNull() - } - - @Test - fun argumentCaptor_multipleValues() { - /* Given */ - val date: Date = mock() - - /* When */ - date.time = 5L - date.time = 7L - - /* Then */ - val captor = argumentCaptor() - 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() - verify(m, times(2)).nullableString(captor.capture()) - expect(captor.allValues).toBe(listOf("test", null)) - } - - @Test - fun argumentCaptor_callProperties() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.int(1) - m.int(2) - m.int(3) - m.int(4) - m.int(5) - - /* Then */ - argumentCaptor().apply { - verify(m, times(5)).int(capture()) - - expect(firstValue).toBe(1) - expect(secondValue).toBe(2) - expect(thirdValue).toBe(3) - expect(lastValue).toBe(5) - } - } - - @Test(expected = IndexOutOfBoundsException::class) - fun argumentCaptor_callPropertyNotAvailable() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.int(1) - - /* Then */ - argumentCaptor().apply { - verify(m).int(capture()) - - expect(secondValue).toBe(2) - } - } -} diff --git a/mockito-kotlin/src/test/kotlin/BaseTest.kt b/mockito-kotlin/src/test/kotlin/BaseTest.kt deleted file mode 100644 index ba2ef1f..0000000 --- a/mockito-kotlin/src/test/kotlin/BaseTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -import com.nhaarman.mockito_kotlin.mockMakerInlineEnabled -import org.junit.After -import org.junit.Before - -abstract class BaseTest { - - @Before - open fun setup() { - mockMakerInlineEnabled = false - } - - @After - open fun tearDown() { - mockMakerInlineEnabled = null - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/Classes.kt b/mockito-kotlin/src/test/kotlin/Classes.kt deleted file mode 100644 index 0657a94..0000000 --- a/mockito-kotlin/src/test/kotlin/Classes.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* -* The MIT License -* -* Copyright (c) 2016 Niek Haarman -* Copyright (c) 2007 Mockito contributors -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -open class Open { - open fun go(vararg arg: Any?) { - } - - open fun modifiesContents(a: IntArray) { - for (i in 0..a.size - 1) { - a[i] = a[i] + 1 - } - } - - open fun stringResult() = "Default" -} - -class Closed - -interface Methods { - - fun intArray(i: IntArray) - fun closed(c: Closed) - fun closedArray(a: Array) - fun closedNullableArray(a: Array) - fun closedCollection(c: Collection) - fun closedList(c: List) - fun closedStringMap(m: Map) - fun closedSet(s: Set) - fun string(s: String) - fun int(i: Int) - fun closedVararg(vararg c: Closed) - fun throwableClass(t: ThrowableClass) - fun nullableString(s: String?) - - fun stringResult(): String - fun nullableStringResult(): String? - fun builderMethod(): Methods -} - -interface GenericMethods { - fun genericMethod(): T -} - -class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt b/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt deleted file mode 100644 index 15f0aaf..0000000 --- a/mockito-kotlin/src/test/kotlin/CreateInstanceTest.kt +++ /dev/null @@ -1,562 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockito_kotlin.MockitoKotlin -import com.nhaarman.mockito_kotlin.createInstance -import org.junit.Test -import java.util.* -import kotlin.reflect.KClass - -class CreateInstanceTest : BaseTest() { - - @Test - fun byte() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun short() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun int() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun long() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun double() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBeIn(-0.000001..0.000001) - } - - @Test - fun float() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBeIn(-0.000001f..0.000001f) - } - - @Test - fun boolean() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(true) - } - - @Test - fun string() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe("") - } - - @Test - fun byteArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun shortArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun intArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun longArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun doubleArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun floatArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun classArray_usingAny() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toBeInstanceOf>() - } - - @Test - fun closedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun closedClass_withOpenParameter() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun closedClass_withClosedParameter() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun singleParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun twoParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun threeParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun fourParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun fiveParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun sixParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun sevenParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedSingleParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedTwoParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedThreeParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedFourParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedFiveParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedSixParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedSevenParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun parameterizedClass() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nullableParameterClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun stringList() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun enum() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(MyEnum.VALUE) - } - - @Test - fun unit() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(Unit) - } - - @Test - fun privateClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun classObject() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun kClassObject() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun uuid() { - /** - * The UUID class has a single-argument constructor that expects an array with some specific contents. - * We avoid these types of constructors by calling another constructor, if available. - * In this case, UUID(Long, Long). - */ - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(UUID(0, 0)) - } - - @Test - fun registeredInstanceCreator() { - /* Given */ - MockitoKotlin.registerInstanceCreator { ForbiddenConstructor(2) } - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun failedConstructor_throwsDescriptiveError() { - expectErrorWithMessage("Could not create an instance of class") on { - createInstance() - } - } - - @Test - fun defaultEmptyConstructor_takesSimplestConstructor() { - /* When */ - val result = createInstance(WithDefaultEmptyConstructor::class) - - /* Then */ - expect(result).toNotBeNull() - } - - /** - * Bug: When the copy constructor is selected, we end up with an infinite - * loop. Instead, we want to select a constructor that doesn't - * take in a parameter with the same type as the one we are building. - * - * GIVEN a class with a copy constructor (in the case of the bug, the copy - * constructor has to be selected, so it must have fewer parameters - * than all other constructors) - * WHEN we make an instance of the given class - * THEN we expect that the new, non-null instance will be created without - * an exception - */ - @Test - fun copyConstructorDoesNotCauseException() { - /* When */ - val result = createInstance(WithCopyConstructor::class) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun optionalParametersAreSkippedWhenSorting() { - /* When */ - val result = createInstance(WithDefaultParameters::class) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun defaultValuesAreUsedWithOptionalParameters() { - /* When */ - val result = createInstance(WithDefaultParameters::class) - - /* Then */ - expect(result.first).toBe(1) - expect(result.second).toBe(2) - } - - @Test - fun sealedClass() { - /* When */ - val result = createInstance(MySealedClass::class) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun sealedClassMember() { - /* When */ - val result = createInstance(MySealedClass.MySealedClassMember::class) - - /* Then */ - expect(result).toNotBeNull() - } - - private class PrivateClass private constructor(val data: String) - - class ClosedClass - class ClosedParameterizedClass(val open: Open) - class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) - - class SingleParameterClass(val first: Byte) - class TwoParameterClass(val first: Byte, val second: Short) - class ThreeParameterClass(val first: Byte, val second: Short, val third: Int) - class FourParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double) - class FiveParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float) - class SixParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long) - class SevenParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long, val seventh: String) - - class NestedSingleParameterClass(val nested: SingleParameterClass) - class NestedTwoParameterClass(val nested: TwoParameterClass) - class NestedThreeParameterClass(val nested: ThreeParameterClass) - class NestedFourParameterClass(val nested: FourParameterClass) - class NestedFiveParameterClass(val nested: FiveParameterClass) - class NestedSixParameterClass(val nested: SixParameterClass) - class NestedSevenParameterClass(val nested: SevenParameterClass) - - class ParameterizedClass(val t: T) - class NullableParameterClass(val s: String?) - - class ForbiddenConstructor { - - constructor() { - throw AssertionError("Forbidden.") - } - - constructor(@Suppress("UNUSED_PARAMETER") value: Int) { - } - } - - class WithDefaultEmptyConstructor() { - constructor(@Suppress("UNUSED_PARAMETER") c: ForbiddenConstructor) : this() - } - - /** - * Bug: When the copy constructor is selected, then create instance gets - * into an infinite loop. We should never use the copy constructor in - * createInstance. - */ - data class WithCopyConstructor private constructor(val x: String, - val y: String) { - constructor(other: WithCopyConstructor) : this(other.x, other.y) - } - - /** - * A class that uses default parameters, but with a constructor without parameters that fails. - * This is to make sure default parameters are not counted when sorting by parameter size. - */ - class WithDefaultParameters constructor(val first: Int = 1, val second: Int = 2) { - - constructor(@Suppress("UNUSED_PARAMETER") first: Int) : this() { - error("Should not be called") - } - } - - enum class MyEnum { VALUE, ANOTHER_VALUE } -} - -sealed class MySealedClass { - class MySealedClassMember : MySealedClass() -} diff --git a/mockito-kotlin/src/test/kotlin/EqTest.kt b/mockito-kotlin/src/test/kotlin/EqTest.kt deleted file mode 100644 index df993bf..0000000 --- a/mockito-kotlin/src/test/kotlin/EqTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.eq -import com.nhaarman.mockito_kotlin.mock -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.mockito.Mockito - -class EqTest : BaseTest() { - - private val interfaceInstance: MyInterface = MyClass() - private val openClassInstance: MyClass = MyClass() - private val closedClassInstance: ClosedClass = ClosedClass() - - private lateinit var doAnswer: Open - - @Before - override fun setup() { - super.setup() - - /* Create a proper Mockito state */ - doAnswer = Mockito.doAnswer { }.`when`(mock()) - } - - @After - override fun tearDown() { - super.tearDown() - - /* Close `any` Mockito state */ - doAnswer.go(0) - } - - @Test - fun eqInterfaceInstance() { - /* When */ - val result = eq(interfaceInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun eqOpenClassInstance() { - /* When */ - val result = eq(openClassInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun eqClosedClassInstance() { - /* When */ - val result = eq(closedClassInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nullArgument() { - /* Given */ - val s: String? = null - - /* When */ - val result = eq(s) - - /* Then */ - expect(result).toBeNull() - } - - private interface MyInterface - private open class MyClass : MyInterface - class ClosedClass -} - diff --git a/mockito-kotlin/src/test/kotlin/MockTest.kt b/mockito-kotlin/src/test/kotlin/MockTest.kt deleted file mode 100644 index 132c3b7..0000000 --- a/mockito-kotlin/src/test/kotlin/MockTest.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.whenever -import org.junit.Test -import org.mockito.Mockito.RETURNS_DEEP_STUBS -import java.util.* - -class MockTest : BaseTest() { - - private lateinit var propertyInterfaceVariable: MyInterface - private lateinit var propertyClassVariable: MyClass - - @Test - fun localInterfaceValue() { - /* When */ - val instance: MyInterface = mock() - - /* Then */ - expect(instance).toNotBeNull() - } - - @Test - fun propertyInterfaceVariable() { - /* When */ - propertyInterfaceVariable = mock() - - /* Then */ - expect(propertyInterfaceVariable).toNotBeNull() - } - - @Test - fun localClassValue() { - /* When */ - val instance: MyClass = mock() - - /* Then */ - expect(instance).toNotBeNull() - } - - @Test - fun propertyClassVariable() { - /* When */ - propertyClassVariable = mock() - - /* Then */ - expect(propertyClassVariable).toNotBeNull() - } - - @Test - fun untypedVariable() { - /* When */ - val instance = mock() - - expect(instance).toNotBeNull() - } - - @Test - fun deepStubs() { - val cal: Calendar = mock(RETURNS_DEEP_STUBS) - whenever(cal.time.time).thenReturn(123L) - expect(cal.time.time).toBe(123L) - } - - private interface MyInterface - private open class MyClass -} - diff --git a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt b/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt deleted file mode 100644 index dceeb41..0000000 --- a/mockito-kotlin/src/test/kotlin/MockitoKotlinTest.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* -import org.junit.After -import org.junit.Test - -class MockitoKotlinTest : BaseTest() { - - @After - fun teardown() { - MockitoKotlin.resetInstanceCreators() - } - - @Test - fun register() { - /* Given */ - val closed = Closed() - MockitoKotlin.registerInstanceCreator { closed } - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(closed) - } - - @Test - fun unregister() { - /* Given */ - val closed = Closed() - MockitoKotlin.registerInstanceCreator { closed } - MockitoKotlin.unregisterInstanceCreator() - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeTheSameAs(closed) - } - - @Test - fun usingInstanceCreatorInsideLambda() { - MockitoKotlin.registerInstanceCreator { CreateInstanceTest.ForbiddenConstructor(2) } - - mock { - on { doSomething(any()) } doReturn "" - } - } - - interface TestClass { - - fun doSomething(c: CreateInstanceTest.ForbiddenConstructor): String - } -} diff --git a/mockito-kotlin/src/test/kotlin/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/MockitoTest.kt deleted file mode 100644 index 41325ff..0000000 --- a/mockito-kotlin/src/test/kotlin/MockitoTest.kt +++ /dev/null @@ -1,480 +0,0 @@ - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.expect.fail -import com.nhaarman.mockito_kotlin.* -import org.junit.Assume.assumeTrue -import org.junit.Test -import org.mockito.exceptions.base.MockitoAssertionError -import java.io.IOException - -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class MockitoTest : BaseTest() { - - @Test - fun anyString() { - mock().apply { - string("") - verify(this).string(any()) - } - } - - @Test - fun anyClosedClass() { - mock().apply { - closed(Closed()) - verify(this).closed(any()) - } - } - - @Test - fun anyIntArray() { - mock().apply { - intArray(intArrayOf()) - verify(this).intArray(any()) - } - } - - @Test - fun anyClassArray() { - mock().apply { - closedArray(arrayOf(Closed())) - verify(this).closedArray(anyArray()) - } - } - - @Test - fun anyNullableClassArray() { - mock().apply { - closedNullableArray(arrayOf(Closed(), null)) - verify(this).closedNullableArray(anyArray()) - } - } - - @Test - fun anyStringVararg() { - mock().apply { - closedVararg(Closed(), Closed()) - verify(this).closedVararg(anyVararg()) - } - } - - @Test - fun anyNull_neverVerifiesAny() { - mock().apply { - nullableString(null) - verify(this, never()).nullableString(any()) - } - } - - @Test - fun anyNull_verifiesAnyOrNull() { - mock().apply { - nullableString(null) - verify(this).nullableString(anyOrNull()) - } - } - - /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ - @Test - fun anyThrowableWithSingleThrowableConstructor() { - assumeTrue(mockMakerInlineEnabled(javaClass)) - - 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 listArgForWhich() { - mock().apply { - closedList(listOf(Closed(), Closed())) - verify(this).closedList(argForWhich { - size == 2 - }) - } - } - - @Test - fun listArgCheck() { - mock().apply { - closedList(listOf(Closed(), Closed())) - verify(this).closedList(check { - expect(it.size).toBe(2) - }) - } - } - - @Test - fun atLeastXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atLeast(2)).string(any()) - } - } - - @Test - fun testAtLeastOnce() { - mock().apply { - string("") - string("") - - verify(this, atLeastOnce()).string(any()) - } - } - - @Test - fun atMostXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atMost(2)).string(any()) - } - } - - @Test - fun testCalls() { - mock().apply { - string("") - string("") - - inOrder(this).verify(this, calls(2)).string(any()) - } - } - - @Test - fun testClearInvocations() { - val mock = mock().apply { - string("") - } - - clearInvocations(mock) - - verify(mock, never()).string(any()) - } - - @Test - fun testDescription() { - try { - mock().apply { - verify(this, description("Test")).string(any()) - } - throw AssertionError("Verify should throw Exception.") - } catch (e: MockitoAssertionError) { - expect(e.message).toContain("Test") - } - } - - @Test - fun testDoAnswer() { - val mock = mock() - - doAnswer { "Test" } - .whenever(mock) - .stringResult() - - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun testDoCallRealMethod() { - val mock = mock() - - doReturn("Test").whenever(mock).stringResult() - doCallRealMethod().whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("Default") - } - - @Test - fun testDoNothing() { - val spy = spy(Open()) - val array = intArrayOf(3) - - doNothing().whenever(spy).modifiesContents(array) - spy.modifiesContents(array) - - expect(array[0]).toBe(3) - } - - @Test - fun testDoReturnValue() { - val mock = mock() - - doReturn("test").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - } - - @Test - fun testDoReturnNullValue() { - val mock = mock() - - doReturn(null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnNullValues() { - val mock = mock() - - doReturn(null, null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnValues() { - val mock = mock() - - doReturn("test", "test2").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - expect(mock.stringResult()).toBe("test2") - } - - @Test - fun testDoThrowClass() { - val mock = mock() - - doThrow(IllegalStateException::class).whenever(mock).go() - - try { - mock.go() - throw AssertionError("Call should have thrown.") - } catch(e: IllegalStateException) { - } - } - - @Test - fun testDoThrow() { - val mock = mock() - - doThrow(IllegalStateException("test")).whenever(mock).go() - - expectErrorWithMessage("test").on { - mock.go() - } - } - - @Test - fun testMockStubbing_lambda() { - /* Given */ - val mock = mock() { - on { stringResult() } doReturn "A" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testMockStubbing_normalOverridesLambda() { - /* Given */ - val mock = mock() { - on { stringResult() }.doReturn("A") - } - whenever(mock.stringResult()).thenReturn("B") - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("B") - } - - @Test - fun testMockStubbing_methodCall() { - /* Given */ - val mock = mock() - mock { - on(mock.stringResult()).doReturn("A") - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testMockStubbing_builder() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() } doReturn mock - } - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBeTheSameAs(mock) - } - - @Test - fun testMockStubbing_nullable() { - /* Given */ - val mock = mock { - on { nullableStringResult() } doReturn "Test" - } - - /* When */ - val result = mock.nullableStringResult() - - /* Then */ - expect(result).toBe("Test") - } - - @Test - fun testMockStubbing_doThrow() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() } doThrow IllegalArgumentException() - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch(e: IllegalArgumentException) { - } - } - - @Test - fun testMockStubbing_doThrowClass() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() } doThrow IllegalArgumentException::class - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch(e: IllegalArgumentException) { - } - } - - @Test - fun testMockStubbing_doThrowVarargs() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() }.doThrow(IllegalArgumentException(), UnsupportedOperationException()) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch(e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch(e: UnsupportedOperationException) { - } - } - - @Test - fun testMockStubbing_doThrowClassVarargs() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() }.doThrow(IllegalArgumentException::class, UnsupportedOperationException::class) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch(e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch(e: UnsupportedOperationException) { - } - } - - @Test - fun doReturn_withSingleItemList() { - /* Given */ - val mock = mock { - on { stringResult() } doReturn listOf("a", "b") - } - - /* Then */ - expect(mock.stringResult()).toBe("a") - expect(mock.stringResult()).toBe("b") - } - - @Test - fun doReturn_withGenericIntReturnType_on() { - /* Expect */ - expectErrorWithMessage("onGeneric") on { - - /* When */ - mock> { - on { genericMethod() } doReturn 2 - } - } - } - - @Test - fun doReturn_withGenericIntReturnType_onGeneric() { - /* Given */ - val mock = mock> { - onGeneric { genericMethod() } doReturn 2 - } - - /* Then */ - expect(mock.genericMethod()).toBe(2) - } -} diff --git a/mockito-kotlin/src/test/kotlin/SpyTest.kt b/mockito-kotlin/src/test/kotlin/SpyTest.kt deleted file mode 100644 index c673b5f..0000000 --- a/mockito-kotlin/src/test/kotlin/SpyTest.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* -import org.junit.After -import org.junit.Test -import org.mockito.Mockito -import org.mockito.exceptions.base.MockitoException -import java.util.* - -class SpyTest : BaseTest() { - - private val interfaceInstance: MyInterface = MyClass() - private val openClassInstance: MyClass = MyClass() - private val closedClassInstance: ClosedClass = ClosedClass() - - @After - override fun tearDown() { - super.tearDown() - Mockito.validateMockitoUsage() - } - - @Test - fun spyInterfaceInstance() { - /* When */ - val result = spy(interfaceInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun spyOpenClassInstance() { - /* When */ - val result = spy(openClassInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun doReturnWithSpy() { - val date = spy(Date()) - doReturn(123L).whenever(date).time - expect(date.time).toBe(123L) - } - - @Test - fun doNothingWithSpy() { - val date = spy(Date(0)) - doNothing().whenever(date).time = 5L - date.time = 5L; - expect(date.time).toBe(0L) - } - - @Test(expected = IllegalArgumentException::class) - fun doThrowWithSpy() { - val date = spy(Date(0)) - doThrow(IllegalArgumentException()).whenever(date).time - date.time - } - - @Test - fun doCallRealMethodWithSpy() { - val date = spy(Date(0)) - doReturn(123L).whenever(date).time - doCallRealMethod().whenever(date).time - expect(date.time).toBe(0L) - } - - private interface MyInterface - private open class MyClass : MyInterface - private class ClosedClass -} - diff --git a/mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt deleted file mode 100644 index 2fa5ac2..0000000 --- a/mockito-kotlin/src/test/kotlin/inline/UsingMockMakerInlineTest.kt +++ /dev/null @@ -1,156 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Ian J. De Silva - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockito_kotlin.* -import org.junit.Assume.assumeTrue -import org.junit.Before -import org.junit.Test -import java.io.IOException -import java.math.BigInteger - -class UsingMockMakerInlineTest { - - class ClassToBeMocked { - - fun doSomething(@Suppress("UNUSED_PARAMETER") c: ClassToBeMocked) { - } - - fun doSomethingElse(value: BigInteger): BigInteger { - return value.plus(BigInteger.ONE) - } - } - - @Before - fun setup() { - mockMakerInlineEnabled = null - assumeTrue(mockMakerInlineEnabled(javaClass)) - } - - @Test - fun mockClosedClass() { - /* When */ - val result = mock() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyClosedClass() { - /* Given */ - val mock = mock() - - /* When */ - mock.doSomething(mock) - - /* Then */ - verify(mock).doSomething(any()) - } - - @Test - fun mockClosedFunction_mockStubbing() { - /* Given */ - val mock = mock { - on { doSomethingElse(any()) } doReturn (BigInteger.ONE) - } - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - @Test - fun mockClosedFunction_whenever() { - /* Given */ - val mock = mock() - whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ - @Test - fun anyThrowableWithSingleThrowableConstructor() { - mock().apply { - throwableClass(ThrowableClass(IOException())) - verify(this).throwableClass(any()) - } - } - - @Test - fun createPrimitiveInstance() { - /* When */ - val i = createInstance() - - /* Then */ - expect(i).toBe(0) - } - - @Test - fun createStringInstance() { - /* When */ - val s = createInstance() - - /* Then */ - expect(s).toBe("") - } - - @Test - fun sealedClass_fails() { - /* Expect */ - expectErrorWithMessage("Could not create") on { - - /* When */ - createInstance(MySealedClass::class) - } - } - - @Test - fun sealedClassMember() { - /* When */ - val result = createInstance(MySealedClass.MySealedClassMember::class) - - /* Then */ - expect(result).toNotBeNull() - } - - interface Methods { - - fun throwableClass(t: ThrowableClass) - } - - class ThrowableClass(cause: Throwable) : Throwable(cause) - - sealed class MySealedClass { - class MySealedClassMember : MySealedClass() - } -} diff --git a/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt new file mode 100644 index 0000000..f5b8562 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt @@ -0,0 +1,120 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.* +import org.junit.Test +import java.util.* + +class ArgumentCaptorTest : TestBase() { + + @Test + fun argumentCaptor_withSingleValue() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + val captor = argumentCaptor() + verify(date).time = captor.capture() + expect(captor.lastValue).toBe(5L) + } + + @Test + fun argumentCaptor_withNullValue_usingNonNullable() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.nullableString(null) + + /* Then */ + val captor = argumentCaptor() + verify(m).nullableString(captor.capture()) + expect(captor.lastValue).toBeNull() + } + + @Test + fun argumentCaptor_withNullValue_usingNullable() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.nullableString(null) + + /* Then */ + val captor = nullableArgumentCaptor() + verify(m).nullableString(captor.capture()) + expect(captor.lastValue).toBeNull() + } + + @Test + fun argumentCaptor_multipleValues() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + date.time = 7L + + /* Then */ + val captor = argumentCaptor() + 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() + verify(m, times(2)).nullableString(captor.capture()) + expect(captor.allValues).toBe(listOf("test", null)) + } + + @Test + fun argumentCaptor_callProperties() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.int(1) + m.int(2) + m.int(3) + m.int(4) + m.int(5) + + /* Then */ + argumentCaptor().apply { + verify(m, times(5)).int(capture()) + + expect(firstValue).toBe(1) + expect(secondValue).toBe(2) + expect(thirdValue).toBe(3) + expect(lastValue).toBe(5) + } + } + + @Test(expected = IndexOutOfBoundsException::class) + fun argumentCaptor_callPropertyNotAvailable() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.int(1) + + /* Then */ + argumentCaptor().apply { + verify(m).int(capture()) + + expect(secondValue).toBe(2) + } + } +} diff --git a/mockito-kotlin/src/test/kotlin/test/Classes.kt b/mockito-kotlin/src/test/kotlin/test/Classes.kt new file mode 100644 index 0000000..eca8c1c --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/Classes.kt @@ -0,0 +1,66 @@ +package test/* +* The MIT License +* +* Copyright (c) 2016 Niek Haarman +* Copyright (c) 2007 Mockito contributors +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +open class Open { + open fun go(vararg arg: Any?) { + } + + open fun modifiesContents(a: IntArray) { + for (i in 0..a.size - 1) { + a[i] = a[i] + 1 + } + } + + open fun stringResult() = "Default" +} + +class Closed + +interface Methods { + + fun intArray(i: IntArray) + fun closed(c: Closed) + fun closedArray(a: Array) + fun closedNullableArray(a: Array) + fun closedCollection(c: Collection) + fun closedList(c: List) + fun closedStringMap(m: Map) + fun closedSet(s: Set) + fun string(s: String) + fun int(i: Int) + fun closedVararg(vararg c: Closed) + fun throwableClass(t: ThrowableClass) + fun nullableString(s: String?) + + fun stringResult(): String + fun nullableStringResult(): String? + fun builderMethod(): Methods +} + +interface GenericMethods { + fun genericMethod(): T +} + +class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/test/EqTest.kt b/mockito-kotlin/src/test/kotlin/test/EqTest.kt new file mode 100644 index 0000000..283bc3f --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/EqTest.kt @@ -0,0 +1,101 @@ +package test/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.eq +import com.nhaarman.mockito_kotlin.mock +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito + +class EqTest : TestBase() { + + private val interfaceInstance: MyInterface = MyClass() + private val openClassInstance: MyClass = MyClass() + private val closedClassInstance: ClosedClass = ClosedClass() + + private lateinit var doAnswer: Open + + @Before + override fun setup() { + super.setup() + + /* Create a proper Mockito state */ + doAnswer = Mockito.doAnswer { }.`when`(mock()) + } + + @After + override fun tearDown() { + super.tearDown() + + /* Close `any` Mockito state */ + doAnswer.go(0) + } + + @Test + fun eqInterfaceInstance() { + /* When */ + val result = eq(interfaceInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun eqOpenClassInstance() { + /* When */ + val result = eq(openClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun eqClosedClassInstance() { + /* When */ + val result = eq(closedClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nullArgument() { + /* Given */ + val s: String? = null + + /* When */ + val result = eq(s) + + /* Then */ + expect(result).toBeNull() + } + + private interface MyInterface + private open class MyClass : MyInterface + class ClosedClass +} + diff --git a/mockito-kotlin/src/test/kotlin/test/MockTest.kt b/mockito-kotlin/src/test/kotlin/test/MockTest.kt new file mode 100644 index 0000000..2073399 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/MockTest.kt @@ -0,0 +1,92 @@ +package test/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.whenever +import org.junit.Test +import org.mockito.Mockito.RETURNS_DEEP_STUBS +import java.util.* + +class MockTest : TestBase() { + + private lateinit var propertyInterfaceVariable: MyInterface + private lateinit var propertyClassVariable: MyClass + + @Test + fun localInterfaceValue() { + /* When */ + val instance: MyInterface = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyInterfaceVariable() { + /* When */ + propertyInterfaceVariable = mock() + + /* Then */ + expect(propertyInterfaceVariable).toNotBeNull() + } + + @Test + fun localClassValue() { + /* When */ + val instance: MyClass = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyClassVariable() { + /* When */ + propertyClassVariable = mock() + + /* Then */ + expect(propertyClassVariable).toNotBeNull() + } + + @Test + fun untypedVariable() { + /* When */ + val instance = mock() + + expect(instance).toNotBeNull() + } + + @Test + fun deepStubs() { + val cal: Calendar = mock(RETURNS_DEEP_STUBS) + whenever(cal.time.time).thenReturn(123L) + expect(cal.time.time).toBe(123L) + } + + private interface MyInterface + private open class MyClass +} + diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt new file mode 100644 index 0000000..63bae8c --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -0,0 +1,477 @@ +package test +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.expect.fail +import com.nhaarman.mockito_kotlin.* +import org.junit.Test +import org.mockito.exceptions.base.MockitoAssertionError +import java.io.IOException + +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +class MockitoTest : TestBase() { + + @Test + fun anyString() { + mock().apply { + string("") + verify(this).string(any()) + } + } + + @Test + fun anyClosedClass() { + mock().apply { + closed(Closed()) + verify(this).closed(any()) + } + } + + @Test + fun anyIntArray() { + mock().apply { + intArray(intArrayOf()) + verify(this).intArray(any()) + } + } + + @Test + fun anyClassArray() { + mock().apply { + closedArray(arrayOf(Closed())) + verify(this).closedArray(anyArray()) + } + } + + @Test + fun anyNullableClassArray() { + mock().apply { + closedNullableArray(arrayOf(Closed(), null)) + verify(this).closedNullableArray(anyArray()) + } + } + + @Test + fun anyStringVararg() { + mock().apply { + closedVararg(Closed(), Closed()) + verify(this).closedVararg(anyVararg()) + } + } + + @Test + fun anyNull_neverVerifiesAny() { + mock().apply { + nullableString(null) + verify(this, never()).nullableString(any()) + } + } + + @Test + fun anyNull_verifiesAnyOrNull() { + mock().apply { + nullableString(null) + verify(this).nullableString(anyOrNull()) + } + } + + /** 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 listArgForWhich() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList(argForWhich { + size == 2 + }) + } + } + + @Test + fun listArgCheck() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList(check { + expect(it.size).toBe(2) + }) + } + } + + @Test + fun atLeastXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atLeast(2)).string(any()) + } + } + + @Test + fun testAtLeastOnce() { + mock().apply { + string("") + string("") + + verify(this, atLeastOnce()).string(any()) + } + } + + @Test + fun atMostXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atMost(2)).string(any()) + } + } + + @Test + fun testCalls() { + mock().apply { + string("") + string("") + + inOrder(this).verify(this, calls(2)).string(any()) + } + } + + @Test + fun testClearInvocations() { + val mock = mock().apply { + string("") + } + + clearInvocations(mock) + + verify(mock, never()).string(any()) + } + + @Test + fun testDescription() { + try { + mock().apply { + verify(this, description("Test")).string(any()) + } + throw AssertionError("Verify should throw Exception.") + } catch (e: MockitoAssertionError) { + expect(e.message).toContain("Test") + } + } + + @Test + fun testDoAnswer() { + val mock = mock() + + doAnswer { "Test" } + .whenever(mock) + .stringResult() + + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun testDoCallRealMethod() { + val mock = mock() + + doReturn("Test").whenever(mock).stringResult() + doCallRealMethod().whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("Default") + } + + @Test + fun testDoNothing() { + val spy = spy(Open()) + val array = intArrayOf(3) + + doNothing().whenever(spy).modifiesContents(array) + spy.modifiesContents(array) + + expect(array[0]).toBe(3) + } + + @Test + fun testDoReturnValue() { + val mock = mock() + + doReturn("test").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + } + + @Test + fun testDoReturnNullValue() { + val mock = mock() + + doReturn(null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnNullValues() { + val mock = mock() + + doReturn(null, null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnValues() { + val mock = mock() + + doReturn("test", "test2").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + expect(mock.stringResult()).toBe("test2") + } + + @Test + fun testDoThrowClass() { + val mock = mock() + + doThrow(IllegalStateException::class).whenever(mock).go() + + try { + mock.go() + throw AssertionError("Call should have thrown.") + } catch(e: IllegalStateException) { + } + } + + @Test + fun testDoThrow() { + val mock = mock() + + doThrow(IllegalStateException("test")).whenever(mock).go() + + expectErrorWithMessage("test").on { + mock.go() + } + } + + @Test + fun testMockStubbing_lambda() { + /* Given */ + val mock = mock() { + on { stringResult() } doReturn "A" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testMockStubbing_normalOverridesLambda() { + /* Given */ + val mock = mock() { + on { stringResult() }.doReturn("A") + } + whenever(mock.stringResult()).thenReturn("B") + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("B") + } + + @Test + fun testMockStubbing_methodCall() { + /* Given */ + val mock = mock() + mock { + on(mock.stringResult()).doReturn("A") + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testMockStubbing_builder() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doReturn mock + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBeTheSameAs(mock) + } + + @Test + fun testMockStubbing_nullable() { + /* Given */ + val mock = mock { + on { nullableStringResult() } doReturn "Test" + } + + /* When */ + val result = mock.nullableStringResult() + + /* Then */ + expect(result).toBe("Test") + } + + @Test + fun testMockStubbing_doThrow() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doThrow IllegalArgumentException() + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + } + + @Test + fun testMockStubbing_doThrowClass() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doThrow IllegalArgumentException::class + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + } + + @Test + fun testMockStubbing_doThrowVarargs() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() }.doThrow(IllegalArgumentException(), UnsupportedOperationException()) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: UnsupportedOperationException) { + } + } + + @Test + fun testMockStubbing_doThrowClassVarargs() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() }.doThrow(IllegalArgumentException::class, UnsupportedOperationException::class) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch(e: UnsupportedOperationException) { + } + } + + @Test + fun doReturn_withSingleItemList() { + /* Given */ + val mock = mock { + on { stringResult() } doReturn listOf("a", "b") + } + + /* Then */ + expect(mock.stringResult()).toBe("a") + expect(mock.stringResult()).toBe("b") + } + + @Test + fun doReturn_withGenericIntReturnType_on() { + /* Expect */ + expectErrorWithMessage("onGeneric") on { + + /* When */ + mock> { + on { genericMethod() } doReturn 2 + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_onGeneric() { + /* Given */ + val mock = mock> { + onGeneric { genericMethod() } doReturn 2 + } + + /* Then */ + expect(mock.genericMethod()).toBe(2) + } +} diff --git a/mockito-kotlin/src/test/kotlin/test/SpyTest.kt b/mockito-kotlin/src/test/kotlin/test/SpyTest.kt new file mode 100644 index 0000000..ee1e2c6 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/SpyTest.kt @@ -0,0 +1,98 @@ +package test/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.* +import org.junit.After +import org.junit.Test +import org.mockito.Mockito +import org.mockito.exceptions.base.MockitoException +import java.util.* + +class SpyTest : TestBase() { + + private val interfaceInstance: MyInterface = MyClass() + private val openClassInstance: MyClass = MyClass() + private val closedClassInstance: ClosedClass = ClosedClass() + + @After + override fun tearDown() { + super.tearDown() + Mockito.validateMockitoUsage() + } + + @Test + fun spyInterfaceInstance() { + /* When */ + val result = spy(interfaceInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun spyOpenClassInstance() { + /* When */ + val result = spy(openClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun doReturnWithSpy() { + val date = spy(Date()) + doReturn(123L).whenever(date).time + expect(date.time).toBe(123L) + } + + @Test + fun doNothingWithSpy() { + val date = spy(Date(0)) + doNothing().whenever(date).time = 5L + date.time = 5L; + expect(date.time).toBe(0L) + } + + @Test(expected = IllegalArgumentException::class) + fun doThrowWithSpy() { + val date = spy(Date(0)) + doThrow(IllegalArgumentException()).whenever(date).time + date.time + } + + @Test + fun doCallRealMethodWithSpy() { + val date = spy(Date(0)) + doReturn(123L).whenever(date).time + doCallRealMethod().whenever(date).time + expect(date.time).toBe(0L) + } + + private interface MyInterface + private open class MyClass : MyInterface + private class ClosedClass +} + diff --git a/mockito-kotlin/src/test/kotlin/test/TestBase.kt b/mockito-kotlin/src/test/kotlin/test/TestBase.kt new file mode 100644 index 0000000..fb00e2b --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/TestBase.kt @@ -0,0 +1,18 @@ +package test + +import com.nhaarman.mockito_kotlin.createinstance.mockMakerInlineEnabled +import org.junit.After +import org.junit.Before + +abstract class TestBase { + + @Before + open fun setup() { + mockMakerInlineEnabled = false + } + + @After + open fun tearDown() { + mockMakerInlineEnabled = null + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt new file mode 100644 index 0000000..8407727 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt @@ -0,0 +1,621 @@ +package test.createinstance + +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockito_kotlin.MockitoKotlin +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.createinstance.InstanceCreator +import com.nhaarman.mockito_kotlin.doReturn +import com.nhaarman.mockito_kotlin.mock +import org.junit.After +import org.junit.Test +import test.Closed +import test.Open +import test.TestBase +import java.util.* +import kotlin.reflect.KClass + +class InstanceCreatorTest : TestBase() { + + private val instanceCreator = InstanceCreator() + + private inline fun createInstance() = instanceCreator.createInstance(T::class) + + @After + fun teardown() { + MockitoKotlin.resetInstanceCreators() + } + + @Test + fun byte() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun short() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun int() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun long() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(0) + } + + @Test + fun double() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBeIn(-0.000001..0.000001) + } + + @Test + fun float() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBeIn(-0.000001f..0.000001f) + } + + @Test + fun boolean() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(true) + } + + @Test + fun string() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe("") + } + + @Test + fun byteArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun shortArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun intArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun longArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun doubleArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun floatArray() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun classArray_usingAny() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toBeInstanceOf>() + } + + @Test + fun closedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun closedClass_withOpenParameter() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun closedClass_withClosedParameter() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun singleParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun twoParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun threeParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun fourParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun fiveParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun sixParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun sevenParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedSingleParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedTwoParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedThreeParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedFourParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedFiveParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedSixParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nestedSevenParameterizedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun parameterizedClass() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nullableParameterClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun stringList() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun enum() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(MyEnum.VALUE) + } + + @Test + fun unit() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(Unit) + } + + @Test + fun privateClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun classObject() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun kClassObject() { + /* When */ + val result = createInstance>() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun uuid() { + /** + * The UUID class has a single-argument constructor that expects an array with some specific contents. + * We avoid these types of constructors by calling another constructor, if available. + * In this case, UUID(Long, Long). + */ + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(UUID(0, 0)) + } + + @Test + fun registeredInstanceCreator() { + /* Given */ + MockitoKotlin.registerInstanceCreator { ForbiddenConstructor(2) } + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun failedConstructor_throwsDescriptiveError() { + expectErrorWithMessage("Could not create an instance of class") on { + createInstance() + } + } + + @Test + fun defaultEmptyConstructor_takesSimplestConstructor() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + /** + * Bug: When the copy constructor is selected, we end up with an infinite + * loop. Instead, we want to select a constructor that doesn't + * take in a parameter with the same type as the one we are building. + * + * GIVEN a class with a copy constructor (in the case of the bug, the copy + * constructor has to be selected, so it must have fewer parameters + * than all other constructors) + * WHEN we make an instance of the given class + * THEN we expect that the new, non-null instance will be created without + * an exception + */ + @Test + fun copyConstructorDoesNotCauseException() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun optionalParametersAreSkippedWhenSorting() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun defaultValuesAreUsedWithOptionalParameters() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result.first).toBe(1) + expect(result.second).toBe(2) + } + + @Test + fun sealedClass() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun sealedClassMember() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun register() { + /* Given */ + val closed = Closed() + MockitoKotlin.registerInstanceCreator { closed } + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toBe(closed) + } + + @Test + fun unregister() { + /* Given */ + val closed = Closed() + MockitoKotlin.registerInstanceCreator { closed } + MockitoKotlin.unregisterInstanceCreator() + + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeTheSameAs(closed) + } + + @Test + fun usingInstanceCreatorInsideLambda() { + MockitoKotlin.registerInstanceCreator { InstanceCreatorTest.ForbiddenConstructor(2) } + + mock { + on { doSomething(any()) } doReturn "" + } + } + + interface TestClass { + + fun doSomething(c: InstanceCreatorTest.ForbiddenConstructor): String + } + + private class PrivateClass private constructor(val data: String) + + class ClosedClass + class ClosedParameterizedClass(val open: Open) + class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) + + class SingleParameterClass(val first: Byte) + class TwoParameterClass(val first: Byte, val second: Short) + class ThreeParameterClass(val first: Byte, val second: Short, val third: Int) + class FourParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double) + class FiveParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float) + class SixParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long) + class SevenParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long, val seventh: String) + + class NestedSingleParameterClass(val nested: SingleParameterClass) + class NestedTwoParameterClass(val nested: TwoParameterClass) + class NestedThreeParameterClass(val nested: ThreeParameterClass) + class NestedFourParameterClass(val nested: FourParameterClass) + class NestedFiveParameterClass(val nested: FiveParameterClass) + class NestedSixParameterClass(val nested: SixParameterClass) + class NestedSevenParameterClass(val nested: SevenParameterClass) + + class ParameterizedClass(val t: T) + class NullableParameterClass(val s: String?) + + class ForbiddenConstructor { + + constructor() { + throw AssertionError("Forbidden.") + } + + constructor(@Suppress("UNUSED_PARAMETER") value: Int) { + } + } + + class WithDefaultEmptyConstructor() { + constructor(@Suppress("UNUSED_PARAMETER") c: ForbiddenConstructor) : this() + } + + /** + * Bug: When the copy constructor is selected, then create instance gets + * into an infinite loop. We should never use the copy constructor in + * createInstance. + */ + data class WithCopyConstructor private constructor(val x: String, + val y: String) { + constructor(other: WithCopyConstructor) : this(other.x, other.y) + } + + /** + * A class that uses default parameters, but with a constructor without parameters that fails. + * This is to make sure default parameters are not counted when sorting by parameter size. + */ + class WithDefaultParameters constructor(val first: Int = 1, val second: Int = 2) { + + constructor(@Suppress("UNUSED_PARAMETER") first: Int) : this() { + error("Should not be called") + } + } + + enum class MyEnum { VALUE, ANOTHER_VALUE } +} + +sealed class MySealedClass { + class MySealedClassMember : MySealedClass() +} diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt new file mode 100644 index 0000000..7527c61 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt @@ -0,0 +1,77 @@ +package test.createinstance + +import com.nhaarman.mockito_kotlin.* +import com.nhaarman.mockito_kotlin.createinstance.NonNullProvider +import com.nhaarman.mockito_kotlin.createinstance.NonNullProviderImpl +import org.junit.Test +import test.TestBase + +class NonNullProviderImplTest : TestBase() { + + @Test(expected = IllegalStateException::class) + fun createInstance_withoutDelegates_throwsException() { + /* Given */ + val nonNullProvider = NonNullProviderImpl(emptyList()) + + /* When */ + nonNullProvider.createInstance(String::class) + } + + @Test + fun createInstance_withSingleDelegate_callsThatDelegate() { + /* Given */ + val delegate = mock() + val nonNullProvider = NonNullProviderImpl(listOf(delegate)) + + /* When */ + nonNullProvider.createInstance(String::class) + + /* Then */ + verify(delegate).createInstance(String::class) + } + + @Test(expected = UnsupportedOperationException::class) + fun createInstance_withSingleDelegateThatFails_throwsException() { + /* Given */ + val delegate = mock { + on { createInstance(any()) } doThrow UnsupportedOperationException() + } + val nonNullProvider = NonNullProviderImpl(listOf(delegate)) + + /* When */ + nonNullProvider.createInstance(String::class) + } + + @Test + fun createInstance_withTwoDelegates_doesNotCallSecondDelegate() { + /* Given */ + val delegate1 = mock() + val delegate2 = mock() + val nonNullProvider = NonNullProviderImpl(listOf(delegate1, delegate2)) + + /* When */ + nonNullProvider.createInstance(String::class) + + /* Then */ + verify(delegate1).createInstance(String::class) + verify(delegate2, never()).createInstance(String::class) + } + + @Test + fun createInstance_withTwoDelegates_firstDelegateFails_callsSecondDelegate() { + /* Given */ + val delegate1 = mock { + on { createInstance(any()) } doThrow UnsupportedOperationException() + } + val delegate2 = mock() + val nonNullProvider = NonNullProviderImpl(listOf(delegate1, delegate2)) + + /* When */ + nonNullProvider.createInstance(String::class) + + /* Then */ + verify(delegate1).createInstance(String::class) + verify(delegate2).createInstance(String::class) + } +} + diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt new file mode 100644 index 0000000..15df3e8 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt @@ -0,0 +1,33 @@ +package test.createinstance + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.createinstance.NullCaster +import org.junit.Test +import test.TestBase + + +class NullCasterTest : TestBase() { + + private val nullCaster = NullCaster() + + @Test + fun createInstance() { + /* When */ + val result = nullCaster.createInstance(String::class) + + /* Then */ + expect(result).toBeNull() + } + + @Test + fun kotlinAcceptsNullValue() { + /* Given */ + val s: String = nullCaster.createInstance(String::class) + + /* When */ + acceptNonNullableString(s) + } + + private fun acceptNonNullableString(s: String) { + } +} diff --git a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt new file mode 100644 index 0000000..ce68b05 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt @@ -0,0 +1,160 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Ian J. De Silva + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockito_kotlin.* +import com.nhaarman.mockito_kotlin.createinstance.InstanceCreator +import com.nhaarman.mockito_kotlin.createinstance.mockMakerInlineEnabled +import org.junit.Assume.assumeTrue +import org.junit.Before +import org.junit.Test +import java.io.IOException +import java.math.BigInteger + +class UsingMockMakerInlineTest { + + class ClassToBeMocked { + + fun doSomething(@Suppress("UNUSED_PARAMETER") c: ClassToBeMocked) { + } + + fun doSomethingElse(value: BigInteger): BigInteger { + return value.plus(BigInteger.ONE) + } + } + + private inline fun createInstance() = InstanceCreator().createInstance(T::class) + + @Before + fun setup() { + mockMakerInlineEnabled = null + assumeTrue(mockMakerInlineEnabled()) + } + + @Test + fun mockClosedClass() { + /* When */ + val result = mock() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass() { + /* Given */ + val mock = mock() + + /* When */ + mock.doSomething(mock) + + /* Then */ + verify(mock).doSomething(any()) + } + + @Test + fun mockClosedFunction_mockStubbing() { + /* Given */ + val mock = mock { + on { doSomethingElse(any()) } doReturn (BigInteger.ONE) + } + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + @Test + fun mockClosedFunction_whenever() { + /* Given */ + val mock = mock() + whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ + @Test + fun anyThrowableWithSingleThrowableConstructor() { + mock().apply { + throwableClass(ThrowableClass(IOException())) + verify(this).throwableClass(any()) + } + } + + @Test + fun createPrimitiveInstance() { + /* When */ + val i = createInstance() + + /* Then */ + expect(i).toBe(0) + } + + @Test + fun createStringInstance() { + /* When */ + val s = createInstance() + + /* Then */ + expect(s).toBe("") + } + + @Test + fun sealedClass_fails() { + /* Expect */ + expectErrorWithMessage("Could not create") on { + + /* When */ + createInstance() + } + } + + @Test + fun sealedClassMember() { + /* When */ + val result = createInstance() + + /* Then */ + expect(result).toNotBeNull() + } + + interface Methods { + + fun throwableClass(t: ThrowableClass) + } + + class ThrowableClass(cause: Throwable) : Throwable(cause) + + sealed class MySealedClass { + class MySealedClassMember : MySealedClass() + } +} -- cgit v1.2.3 From 66d8249d61339a71f4ad0c9efb751d2f89159247 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 12 Nov 2016 22:16:01 +0100 Subject: Also test with Kotlin 1.1 --- .travis.yml | 12 ++++++++---- mockito-kotlin/build.gradle | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4508f2d..88d423b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,17 @@ sudo: false language: java -jdk: -- oraclejdk7 - matrix: include: - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5 + - jdk: oraclejdk7 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M02 + - jdk: oraclejdk8 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5 + - jdk: oraclejdk8 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M02 + env: matrix: diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 32c06da..f19d248 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,11 +3,12 @@ apply from: './publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = '1.0.5' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.5' repositories { mavenCentral() jcenter() + maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1' } } dependencies { @@ -19,6 +20,7 @@ buildscript { repositories { mavenCentral() jcenter() + maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1' } } dependencies { -- cgit v1.2.3 From b50831bf5ada75e313c0d0676008fd2d2aae9795 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 12 Nov 2016 22:41:20 +0100 Subject: Fix release build config --- gradle.properties | 1 - mockito-kotlin/publishing.gradle | 2 -- 2 files changed, 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 92fd338..278ac4e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,4 +24,3 @@ # isRelease = false -publishToLocal = false diff --git a/mockito-kotlin/publishing.gradle b/mockito-kotlin/publishing.gradle index 33f60f3..7cc2391 100644 --- a/mockito-kotlin/publishing.gradle +++ b/mockito-kotlin/publishing.gradle @@ -40,8 +40,6 @@ uploadArchives { ) } - if (publishToLocal) repository(url: mavenLocal().url) - pom.project { name 'Mockito-Kotlin' packaging 'jar' -- cgit v1.2.3 From 59bf311962007b2cbc8046ecc13e17fa3d039140 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 15 Nov 2016 21:47:34 +0100 Subject: Add a lambda to inOrder() for easier verification --- .../main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 1 + mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index bbcce1e..70ef4ab 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -76,6 +76,7 @@ fun doThrow(vararg toBeThrown: Throwable): Stubber = Mockito.doThrow(*toBeThrown fun eq(value: T): T = Mockito.eq(value) ?: value fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks)!! fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! +fun inOrder(vararg mocks: Any, evaluation: InOrder.() -> Unit) = Mockito.inOrder(*mocks).evaluation() inline fun isA(): T? = Mockito.isA(T::class.java) fun isNotNull(): T? = Mockito.isNotNull() diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 63bae8c..5e2f6e2 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -1,4 +1,5 @@ package test + import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail @@ -177,6 +178,23 @@ class MockitoTest : TestBase() { } } + @Test + fun testInOrderWithLambda() { + /* Given */ + val a = mock<() -> Unit>() + val b = mock<() -> Unit>() + + /* When */ + b() + a() + + /* Then */ + inOrder(a, b) { + verify(b).invoke() + verify(a).invoke() + } + } + @Test fun testClearInvocations() { val mock = mock().apply { -- cgit v1.2.3 From e6f6d2c9563a4f958eb52089853ffe9a05adff52 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 15 Nov 2016 21:55:07 +0100 Subject: Update Kotlin to 1.0.5-2 --- .travis.yml | 6 +++--- mockito-kotlin/build.gradle | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 88d423b..19d433b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,13 @@ language: java matrix: include: - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5-2 - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M02 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5 + env: TERM=dumb KOTLIN_VERSION=1.0.5-2 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M02 + env: TERM=dumb KOTLIN_VERSION=1.1-M02 env: diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index f19d248..341a288 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: './publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.5' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.5-2' repositories { mavenCentral() -- cgit v1.2.3 From c974db088c76aec042faef212c63e83d4aaecead Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 15 Nov 2016 22:03:23 +0100 Subject: Update Mockito to 2.2.17 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 341a288..60abc78 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -26,7 +26,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.2.15" + compile "org.mockito:mockito-core:2.2.17" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From acde82f8ac6b2b41210e753bccd7c5083b21ee21 Mon Sep 17 00:00:00 2001 From: ghostbuster91 Date: Wed, 23 Nov 2016 21:09:13 +0100 Subject: Change isA method to return instance of T --- .../main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 2 +- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 70ef4ab..9a67e3c 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -78,7 +78,7 @@ fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks) fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! fun inOrder(vararg mocks: Any, evaluation: InOrder.() -> Unit) = Mockito.inOrder(*mocks).evaluation() -inline fun isA(): T? = Mockito.isA(T::class.java) +inline fun isA(): T = Mockito.isA(T::class.java) ?: createInstance() fun isNotNull(): T? = Mockito.isNotNull() fun isNull(): T? = Mockito.isNull() diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 5e2f6e2..1514a1e 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -492,4 +492,19 @@ class MockitoTest : TestBase() { /* Then */ expect(mock.genericMethod()).toBe(2) } -} + + @Test + fun isA_withNonNullableString() { + mock().apply { + string("") + verify(this).string(isA()) + } + } + @Test + fun isA_withNullableString() { + mock().apply { + nullableString("") + verify(this).nullableString(isA()) + } + } +} \ No newline at end of file -- cgit v1.2.3 From 05a65ecc2977009d5920c2adb58f69f853df4b0d Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 24 Nov 2016 11:16:56 +0100 Subject: Update Mockito to 2.2.22 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 60abc78..7554969 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -26,7 +26,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.2.17" + compile "org.mockito:mockito-core:2.2.22" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From a734cde5f34102f9bb5bda1aca8a7d3f69af1b1c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 24 Nov 2016 13:22:34 +0100 Subject: Test with Kotlin 1.1-M03 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 19d433b..a59c65a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ matrix: - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5-2 - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M02 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M03 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.5-2 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1-M02 + env: TERM=dumb KOTLIN_VERSION=1.1-M03 env: -- cgit v1.2.3 From dc4ab0ab712e62a3bfa3a2698c1efecce771647a Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Dec 2016 12:35:12 +0100 Subject: Update publishing --- mockito-kotlin/build.gradle | 2 ++ mockito-kotlin/publishing.gradle | 55 +++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 7554969..87111b4 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -14,6 +14,8 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.9" + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" + classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" } } diff --git a/mockito-kotlin/publishing.gradle b/mockito-kotlin/publishing.gradle index 7cc2391..c8841e1 100644 --- a/mockito-kotlin/publishing.gradle +++ b/mockito-kotlin/publishing.gradle @@ -1,11 +1,9 @@ -apply plugin: 'maven' apply plugin: 'signing' +apply plugin: 'com.jfrog.bintray' +apply plugin: 'com.github.dcendents.android-maven' group = 'com.nhaarman' version = rootProject.ext.versionName -def sonatypeUsername = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') -def sonatypePassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') - task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' @@ -28,19 +26,10 @@ signing { sign configurations.archives } -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2") { - authentication( - userName: sonatypeUsername, - password: sonatypePassword - ) - } - - pom.project { +install { + repositories.mavenInstaller { + pom { + project { name 'Mockito-Kotlin' packaging 'jar' description 'Using Mockito with Kotlin.' @@ -55,6 +44,7 @@ uploadArchives { licenses { license { name 'MIT' + url 'https://opensource.org/licenses/MIT' distribution 'repo' } } @@ -68,4 +58,35 @@ uploadArchives { } } } +} + +bintray { + user = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') + key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') + + configurations = ['archives'] + + publish = true + + pkg { + repo = 'maven' + name = 'Mockito-Kotlin' + licenses = ['MIT'] + vcsUrl = 'https://github.com/nhaarman/mockito-kotlin.git' + + version { + name = versionName + + gpg { + sign = true + } + + mavenCentralSync { + sync = true + user = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') + password = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') + close = '1' + } + } + } } \ No newline at end of file -- cgit v1.2.3 From 559ffc55708e163105aa14a166f2902c9680d2f6 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Dec 2016 12:47:23 +0100 Subject: Remove deprecated methods --- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 19 ------------------- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 12 ------------ .../test/kotlin/test/createinstance/NullCasterTest.kt | 2 +- 3 files changed, 1 insertion(+), 32 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt index bbf093d..5b5004d 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt @@ -36,10 +36,6 @@ inline fun capture(captor: ArgumentCaptor): T = captor.capt class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass<*>) { - @Deprecated("Use lastValue", ReplaceWith("lastValue")) - val value: T - get() = captor.value - /** * The first captured value of the argument. * @throws IndexOutOfBoundsException if the value is not available. @@ -86,18 +82,3 @@ val ArgumentCaptor.thirdValue: T val ArgumentCaptor.lastValue: T get() = allValues.last() - -/** - * 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(), argThat() or check() instead.", ReplaceWith("check(consumer)"), DeprecationLevel.ERROR) -inline fun capture(noinline consumer: (T) -> Unit): T { - var times = 0 - return argThat { if (++times == 1) consumer.invoke(this); true } -} - -@Deprecated("Use captor.capture() instead.", ReplaceWith("captor.capture()"), DeprecationLevel.ERROR) -inline fun capture(captor: KArgumentCaptor): T = captor.capture() - diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 9a67e3c..86b9713 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -156,15 +156,3 @@ fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(* fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! fun withSettings(): MockSettings = Mockito.withSettings()!! - -@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) -inline fun anyCollection(): Collection = any() - -@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) -inline fun anyList(): List = any() - -@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) -inline fun anySet(): Set = any() - -@Deprecated("Use any() instead.", ReplaceWith("any()"), DeprecationLevel.ERROR) -inline fun anyMap(): Map = any() diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt index 15df3e8..3a89f97 100644 --- a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt @@ -28,6 +28,6 @@ class NullCasterTest : TestBase() { acceptNonNullableString(s) } - private fun acceptNonNullableString(s: String) { + private fun acceptNonNullableString(@Suppress("UNUSED_PARAMETER") s: String) { } } -- cgit v1.2.3 From 5418cfffe1419a0f6a346aa4b07796ebe738280c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Dec 2016 12:59:56 +0100 Subject: Update README.md --- README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 339bf37..5a424b4 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,11 @@ A small library that provides helper functions to work with [Mockito](https://gi ## Install -Mockito-Kotlin is available on Maven Central. +Mockito-Kotlin is available on Maven Central and JCenter. For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` with the latest version: ```groovy -repositories { - mavenCentral() -} -dependencies { - testCompile "com.nhaarman:mockito-kotlin:x.x.x" -} +testCompile "com.nhaarman:mockito-kotlin:x.x.x" ``` ## Example @@ -23,7 +18,7 @@ A test using Mockito-Kotlin typically looks like the following: ```kotlin @Test -fun a(){ +fun doAction_doesSomething(){ /* Given */ val mock = mock { on { getText() } doReturn "text" -- cgit v1.2.3 From 0ba47f463aab83ccb59cc494077b567f58df99b6 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 6 Dec 2016 13:09:29 +0100 Subject: Update dokka plugin --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 87111b4..477ddb6 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -13,7 +13,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.9" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.10" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" } -- cgit v1.2.3 From af1940cf644963bb7f09da6a606b972695498bcf Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 6 Dec 2016 13:10:04 +0100 Subject: Update Mockito to 2.2.28 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 477ddb6..301fd9c 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -28,7 +28,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.2.22" + compile "org.mockito:mockito-core:2.2.28" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From ed6d30dc7ee401901c48a8e2c8e5bf6a123e1312 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 6 Dec 2016 13:13:09 +0100 Subject: Update tagging script --- gradle/scripts/tagging.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/scripts/tagging.gradle b/gradle/scripts/tagging.gradle index e7b4281..907707d 100644 --- a/gradle/scripts/tagging.gradle +++ b/gradle/scripts/tagging.gradle @@ -1,7 +1,7 @@ new ByteArrayOutputStream().withStream { os -> exec { - commandLine 'git', 'describe' + commandLine 'git', 'describe', '--abbrev=0', '--tags' standardOutput = os } -- cgit v1.2.3 From b77d969821a41fa76227c5de9816b243cc3b4e16 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 8 Dec 2016 14:47:47 +0100 Subject: Handle `null` in argument matchers. When stubbing with argument matchers, the following scenario would cause a NullPointerException: ``` whenever(mock.doSomething(argThat { })).thenReturn("") whenever(mock.doSomething(argThat { })).thenReturn("") ``` The second `argThat` invocation returns a `null` value, which gets propagated into the function passed to the first `argThat` invocation. This commit filters `null` values to always evaluate to `false` when provided to an argument matcher. --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 34 ++++++++++++++++++-- mockito-kotlin/src/test/kotlin/test/Classes.kt | 5 ++- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 36 ++++++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 86b9713..935bed7 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -52,9 +52,39 @@ inline fun anyVararg(): T = Mockito.any() ?: createInstance /** Matches any array of type T. */ inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() -inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { it -> (it as T).predicate() } ?: createInstance(T::class) +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ +inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { arg -> arg?.predicate() ?: false } ?: createInstance(T::class) + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) -inline fun check(noinline predicate: (T) -> Unit) = Mockito.argThat { it -> predicate(it); true } ?: createInstance(T::class) + +/** + * For usage with verification only. + * + * For example: + * verify(myObject).doSomething(check { assertThat(it, is("Test")) }) + * + * @param predicate A function that performs actions to verify an argument [T]. + */ +inline fun check(noinline predicate: (T) -> Unit) = Mockito.argThat { arg -> + if (arg == null) error("""The argument passed to the predicate was null. + +If you are trying to verify an argument to be null, use `isNull()`. +If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. +""".trimIndent()) + predicate(arg) + true +} ?: createInstance(T::class) fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!! diff --git a/mockito-kotlin/src/test/kotlin/test/Classes.kt b/mockito-kotlin/src/test/kotlin/test/Classes.kt index eca8c1c..58dc995 100644 --- a/mockito-kotlin/src/test/kotlin/test/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/test/Classes.kt @@ -1,4 +1,6 @@ -package test/* +package test + +/* * The MIT License * * Copyright (c) 2016 Niek Haarman @@ -55,6 +57,7 @@ interface Methods { fun nullableString(s: String?) fun stringResult(): String + fun stringResult(s: String): String fun nullableStringResult(): String? fun builderMethod(): Methods } diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 1514a1e..d348b1a 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -138,6 +138,17 @@ class MockitoTest : TestBase() { } } + @Test + fun checkWithNullArgument_throwsError() { + mock().apply { + nullableString(null) + + expectErrorWithMessage("null").on { + verify(this).nullableString(check {}) + } + } + } + @Test fun atLeastXInvocations() { mock().apply { @@ -458,6 +469,30 @@ class MockitoTest : TestBase() { } } + @Test + fun stubbingTwiceWithArgumentMatchers() { + /* When */ + val mock = mock { + on { stringResult(argThat { this == "A" }) } doReturn "A" + on { stringResult(argThat { this == "B" }) } doReturn "B" + } + + /* Then */ + expect(mock.stringResult("A")).toBe("A") + expect(mock.stringResult("B")).toBe("B") + } + + @Test + fun stubbingTwiceWithCheckArgumentMatchers_throwsException() { + /* Expect */ + expectErrorWithMessage("null").on { + mock { + on { stringResult(check { }) } doReturn "A" + on { stringResult(check { }) } doReturn "B" + } + } + } + @Test fun doReturn_withSingleItemList() { /* Given */ @@ -500,6 +535,7 @@ class MockitoTest : TestBase() { verify(this).string(isA()) } } + @Test fun isA_withNullableString() { mock().apply { -- cgit v1.2.3 From e07e4194d327e3735e427132fe016ce8a78c33b9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 10 Dec 2016 16:02:40 +0100 Subject: Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index fa6cbc3..ee9389c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,4 +2,3 @@ Thank you for submitting a pull request! But first: - [ ] Can you back your code up with tests? - [ ] Keep your commits clean: [squash your commits if necessary](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History). - - [ ] Make sure you're targeting the `dev` branch with the PR. -- cgit v1.2.3 From 8118f1ae6c78adf09b5434da67c303f336412cb7 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 19 Dec 2016 14:25:43 +0100 Subject: Update Mockito to 2.3.9 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 301fd9c..2b1436d 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -28,7 +28,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.2.28" + compile "org.mockito:mockito-core:2.3.9" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 3c714eba76c591918c03a73214053ee12b19f07b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 19 Dec 2016 14:27:02 +0100 Subject: Update Kotlin to 1.0.5-3 --- .travis.yml | 4 ++-- mockito-kotlin/build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a59c65a..ecc25a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,11 +5,11 @@ language: java matrix: include: - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5-2 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5-3 - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M03 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.0.5-2 + env: TERM=dumb KOTLIN_VERSION=1.0.5-3 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.1-M03 diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 2b1436d..218cec6 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: './publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.5-2' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.5-3' repositories { mavenCentral() -- cgit v1.2.3 From e3344f4754d2ad42c8ae41a129d7d5c2b22d28f6 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 19 Dec 2016 14:40:00 +0100 Subject: Update Gradle wrapper to 3.2.1 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 46b1b27..cf73567 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-all.zip -- cgit v1.2.3 From a1ea33b8824283becfa646870f21abfdfae6894b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 19 Dec 2016 14:41:04 +0100 Subject: Update Dokka to 0.9.11 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 218cec6..c219d43 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -13,7 +13,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.10" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.11" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" } -- cgit v1.2.3 From 4d6c490c6c9210bfa0628ce35db5aa7caa67eb00 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 19 Dec 2016 14:47:02 +0100 Subject: Add argWhere function --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 8 + mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 10 ++ tmp.txt | 181 +++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 tmp.txt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 935bed7..c64a514 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -68,6 +68,14 @@ inline fun argThat(noinline predicate: T.() -> Boolean) = Mock */ inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate A function that returns `true` when given [T] matches the predicate. + */ +inline fun argWhere(noinline predicate: (T) -> Boolean) = argThat(predicate) + /** * For usage with verification only. * diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index d348b1a..65670f2 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -128,6 +128,16 @@ class MockitoTest : TestBase() { } } + @Test + fun listArgWhere() { + mock().apply { + closedList(listOf(Closed(), Closed())) + verify(this).closedList(argWhere { + it.size == 2 + }) + } + } + @Test fun listArgCheck() { mock().apply { diff --git a/tmp.txt b/tmp.txt new file mode 100644 index 0000000..171670e --- /dev/null +++ b/tmp.txt @@ -0,0 +1,181 @@ +a1ea33b Update Dokka to 0.9.11 +e3344f4 Update Gradle wrapper to 3.2.1 +3c714eb Update Kotlin to 1.0.5-3 +8118f1a Update Mockito to 2.3.9 +327d431 Merge pull request #137 from nhaarman/release-1.0.1 +8c9e5d7 Merge branch 'master' into dev +e07e419 Update PULL_REQUEST_TEMPLATE.md +263344f Merge pull request #135 from nhaarman/handle-null-in-argumentmatcher +b77d969 Handle `null` in argument matchers. +543238f Merge pull request #131 from nhaarman/release-1.0.0 +ed6d30d Update tagging script +af1940c Update Mockito to 2.2.28 +0ba47f4 Update dokka plugin +04cd24d Merge pull request #130 from nhaarman/release-1.0.0-RC1 +5418cff Update README.md +559ffc5 Remove deprecated methods +dc4ab0a Update publishing +a734cde Test with Kotlin 1.1-M03 +7fb4bd9 Merge pull request #127 from nhaarman/release-0.12.2 +05a65ec Update Mockito to 2.2.22 +62f3170 Merge branch 'ghostbuster91-FeatureRequest_isAclassShouldReturnInstance' into dev +acde82f Change isA method to return instance of T +72279be Merge pull request #123 from nhaarman/release-0.12.1 +c974db0 Update Mockito to 2.2.17 +e6f6d2c Update Kotlin to 1.0.5-2 +b665264 Merge pull request #122 from nhaarman/inorder-lambda +59bf311 Add a lambda to inOrder() for easier verification +b50831b Fix release build config +ebc6147 Merge pull request #121 from nhaarman/release-0.12.0 +66d8249 Also test with Kotlin 1.1 +cdc34a0 Merge pull request #120 from nhaarman/cast-null +18ed580 Use `null as T` to create instances +ae1d863 Merge pull request #119 from nhaarman/clean-tests +ab1eb0d Use same test source for inline tests +2b31ed7 Merge branch 'master' into dev +57d0d8b Merge pull request #118 from nhaarman/improve-argumentcaptor +81a0996 Add value shortcuts to ArgumentCaptor +37f1717 Merge pull request #117 from nhaarman/nullable-eq +1eead3e Return passed value instead of trying to create an instance +a831657 Update Mockito to 2.2.15 +5f12032 Merge pull request #113 from rongi/patch-1 +e7ed7cb Update to Kotlin 1.0.5 +27c6bf6 Merge pull request #111 from nhaarman/release-0.11.0 +771f761 Merge pull request #110 from nhaarman/graciously_fail +c8fecf0 Try to use constructor when mocking fails +fa27978 Merge pull request #109 from nhaarman/nullable-mockstubbing +f353562 Accept nullable return types when stubbing +50a1b91 Merge pull request #108 from nhaarman/release-0.10.1 +c3f7e68 Merge pull request #107 from nhaarman/create-primitive-instance +0615231 Don't try to mock primitive/wrapper instances +494e7ca Merge pull request #105 from nhaarman/fix-generic-returntype-npe +113d9e9 Catch an NPE thrown by the Kotlin type checker in the Mockito library. +3b5c40a Merge pull request #102 from nhaarman/release-0.10.0 +6af0904 Update Mockito to 2.2.9 +287065a Merge pull request #101 from nhaarman/skip-optional-parameters +42cee20 Don't count optional parameters when trying to find an easy constructor +e43ccea Merge pull request #100 from nhaarman/nullable-argumentcaptor +086d482 Add `nullableArgumentCaptor` to be able to work with lists of nullables +7b6c5b7 Merge branch 'desilvai-dev' into dev +395e578 Fixed infinite loop caused by 'copy constructors' invoked by createInstance. The fix is to skip all constructors that take in parameters with same type as the object we are trying to build. +24108bd Merge pull request #98 from nhaarman/release-0.9.0 +6126454 Update version badge +5a31910 Merge pull request #97 from nhaarman/deprecation-levels +63826bf Upgrade deprecation levels to ERROR +3db9e21 Update Mockito to 2.2.6 +5884adc Merge pull request #96 from nhaarman/dokka +fb74552 Use dokka do generate docs +f165976 Merge pull request #95 from nhaarman/publish-to-maven-central +8e083ad Publish to Maven Central instead of Bintray +5878bbe Merge pull request #93 from nhaarman/release-0.8.0 +d556691 Update Mockito to 2.2.1 +6ee75f7 Merge pull request #92 from nhaarman/create-array-instance +0b43d0b Use the java class' name to create an array instance +cd16b04 Merge pull request #91 from nhaarman/improve-captors +80dbefd Improve argument captors +fd98501 Merge pull request #90 from nhaarman/ongoingstubbing-dothrow +94b3c65 Added doThrow methods to OngoingStubbing +85bb5e4 Merge branch 'desilvai-dev' into dev +6965414 Fix compatibility with mock-maker-inline for mocking final classes +ea6e64c Merge pull request #85 from nhaarman/release-0.7.0 +36e3dd5 Merge pull request #84 from nhaarman/fix-createinstance-from-lambda +1d65fc0 Strip methods from file identifiers. +1025568 Merge pull request #83 from nhaarman/stubbing-mock-reference +0c3e137 Provide mock instance to stubbing method in mock() +3f73e27 Merge pull request #82 from nhaarman/mockito-rc2 +e549d8d Update Mockito dependency to 2.1.0 +0886485 Update Mockito dependency to RC2 +2d724bc Merge pull request #74 from viniciussoares/dev +f2ed004 Upgrade Kotlin to 1.0.4. +9c4234e Merge pull request #73 from nhaarman/release-0.6.2 +cf06555 Merge pull request #72 from nhaarman/any-or-null +9351840 Include `anyOrNull()` +3d64888 Merge pull request #71 from jpshelley/mockito-2.1.0-RC.1 +6862ea5 update to RC.1 +4c09ebc Merge branch 'master' into dev +f18d86e Merge pull request #70 from nhaarman/release-0.6.1 +650e293 Update README.md +f291e71 Merge pull request #69 from nhaarman/argforwhich +9a3b7de Introduce argForWhich() as an alias for argThat() +8d53bad Merge pull request #68 from nhaarman/fix-anyarrayofnullables +9507a20 Make anyArray() accept nullable types. +7dcebc9 Stop. Sending me. Emails. +c029a13 Merge pull request #67 from nhaarman/deprecate-deprecated-methods +400b1cc Deprecate methods that are deprecated in Mockito. +c06d37f Merge pull request #64 from nhaarman/fix-simplest-constructor +18be968 Improve `easiestConstructor()` to sort by parameters size. +855c14b Update gradle wrapper to 3.0 +58013d8 Update dependencies +6110a90 Update Mockito version to 2.1.0-beta.125 +6cf8557 Update README.md +d07a2c9 Merge pull request #59 from nhaarman/release-0.6.0 +2a2ed98 Merge pull request #58 from nhaarman/mock-stubbing +ecfaf58 Add infix modifiers to doReturn methods +2d4eef9 Accept a stubbing lambda in mock() +84fb7e0 Merge branch 'master' into dev +49d59a6 Merge pull request #55 from sghill/mockito-2.0.99-beta +2f94f52 Upgrade Mockito to 2.0.99-beta +a6f8604 Merge pull request #53 from nhaarman/release-0.5.2 +51385ca Added an example to the Readme on Argument Captors. +6a521ea Make `doReturn` accept null values. +c3e6182 Specify explicit return types for Mockito calls. +6867394 Merge pull request #50 from Zoltu/patch-1 +25fb19c Upgrade Kotlin version to 1.0.3. +e1de1f6 Makes `mock` return non-null types. +bb4ac76 Merge pull request #43 from nhaarman/release-0.5.1 +8e6ab15 Update gradle wrapper version +c400381 Merge pull request #42 from hamen/master +c44c15a Update Kotlin version +62cd94f Merge pull request #38 from nhaarman/release-0.5.0 +aa49bde Merge pull request #23 from nhaarman/instance-creators +f765a31 Use instance creators only from single test file. +17dadf9 Update README.md +cddcf7f Introduce instance creators. +4cbd876 Merge pull request #36 from nhaarman/release-0.4.1 +abfc083 Update dependencies +772d0d9 Merge pull request #33 from nhaarman/release-0.4.0 +1322b92 Update dependencies +55e9a3c Merge pull request #30 from nhaarman/release-0.3.1 +df0c3f6 Remove Travis-CI cache +d4e73a9 Merge pull request #29 from nhaarman/uncheckedmock-interceptor +c8d9f68 Unset the MockitoInterceptor for unchecked mocks. +129f9e6 Merge pull request #28 from nhaarman/create-class-objects +ae4ab17 Account for Class when creating instances. +a013a48 Merge pull request #19 from nhaarman/avoid-array-parameters +ea0263d Avoid constructors with an array as a parameter. +48fc1aa Merge pull request #16 from nhaarman/release-0.3.0 +fc95068 Merge branch 'dev' of https://github.com/codeborne/mockito-kotlin into codeborne-dev +5105493 Include more static Mockito methods +9238c4c add simpler capture() method with lambda +ce93783 Merge pull request #12 from codeborne/master +66e3be5 add simplified ArgumentCaptor support +1262c19 add deep stubs test +f6f142a add spy stubbing tests +0efd093 Added PR template +624b7c4 Merge pull request #10 from ViFork/master +334d471 add missing imports +76be5d0 add more missing Mockito methods, especially to be used with spies +40bf7c6 changed kotlin version to 1.0.0 +7cafd23 Merge pull request #7 from nhaarman/release-0.2.0 +8b93c66 Update Kotlin to rc-1036 +8488479 Merge pull request #6 from nhaarman/release-0.1.6 +1d9a588 Use smallest constructor +37ded6f Merge pull request #5 from nhaarman/release-0.1.5 +8157be6 Support Boolean +0665c25 Merge pull request #4 from nhaarman/release-0.1.4 +a873fa7 Support private classes +0cc78ba Merge pull request #3 from nhaarman/release-0.1.3 +65d6a5f Support object instances +c4bde0f Merge pull request #2 from nhaarman/release-0.1.2 +9856798 Proper license +9f1df2d Make sure 'eq' does not return null +90f6598 Merge branch 'master' into dev +b40c9ae Update README.md +ad964f7 Update README.md +92bb350 Cache Travis dependencies +886cad6 Proper version names +139d47c Proper version names +78505b7 Merge pull request #1 from nhaarman/release-0.1.1 +b5a4e87 Support enums +b113029 Upload to Bintray +2f9603a Initial commit -- cgit v1.2.3 From 0e27631cc035a676af210faf79f157202aface99 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 27 Dec 2016 19:18:11 +0100 Subject: Update Kotlin to 1.0.6 --- .travis.yml | 8 ++++---- mockito-kotlin/build.gradle | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index ecc25a5..36ba395 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,13 @@ language: java matrix: include: - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.5-3 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.6 - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M03 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M04 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.0.5-3 + env: TERM=dumb KOTLIN_VERSION=1.0.6 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1-M03 + env: TERM=dumb KOTLIN_VERSION=1.1-M04 env: diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index c219d43..e24a1b2 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: './publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.5-3' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.6' repositories { mavenCentral() -- cgit v1.2.3 From e08b8a0b0c856947bbd43e64211dc3069f513707 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 27 Dec 2016 19:23:07 +0100 Subject: Update sealed member class test --- .../src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt index ce68b05..93c5f9f 100644 --- a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt @@ -23,7 +23,6 @@ */ import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.mockito_kotlin.* import com.nhaarman.mockito_kotlin.createinstance.InstanceCreator import com.nhaarman.mockito_kotlin.createinstance.mockMakerInlineEnabled @@ -129,13 +128,12 @@ class UsingMockMakerInlineTest { } @Test - fun sealedClass_fails() { - /* Expect */ - expectErrorWithMessage("Could not create") on { + fun sealedMemberClass() { + /* When */ + val result = createInstance() - /* When */ - createInstance() - } + /* Then */ + expect(result).toNotBeNull() } @Test -- cgit v1.2.3 From 952d366031741567a2608b61c5aee481a1ad40c7 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 19 Dec 2016 15:12:31 +0100 Subject: Add BDDMockito functions --- .../com/nhaarman/mockito_kotlin/BDDMockito.kt | 13 +++ .../src/test/kotlin/test/BDDMockitoTest.kt | 103 +++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt new file mode 100644 index 0000000..203232d --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt @@ -0,0 +1,13 @@ +package com.nhaarman.mockito_kotlin + +import org.mockito.BDDMockito + +fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing = BDDMockito.given(methodCall) +fun given(methodCall: () -> T) = given(methodCall()) + +fun then(mock: T): BDDMockito.Then = BDDMockito.then(mock) + +infix fun BDDMockito.BDDMyOngoingStubbing.willAnswer(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willAnswer { value() } +infix fun BDDMockito.BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willReturn(value()) +infix fun BDDMockito.BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing = willThrow(value()) + diff --git a/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt new file mode 100644 index 0000000..1df2239 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt @@ -0,0 +1,103 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockito_kotlin.* +import org.junit.Test + +class BDDMockitoTest { + + @Test + fun given_willReturn_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()).willReturn("Test") + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun givenLambda_willReturn_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given { mock.stringResult() }.willReturn("Test") + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun given_willReturnLambda_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()).willReturn { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun givenLambda_willReturnLambda_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given { mock.stringResult() } willReturn { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun given_willAnswer_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()).willAnswer { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun given_willAnswerInfix_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()) willAnswer { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test(expected = IllegalStateException::class) + fun given_willThrowInfix_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()) willThrow { IllegalStateException() } + mock.stringResult() + } + + @Test + fun then() { + /* Given */ + val mock = mock() + whenever(mock.stringResult()).thenReturn("Test") + + /* When */ + mock.stringResult() + + /* Then */ + then(mock).should().stringResult() + } +} -- cgit v1.2.3 From 9f827ebd1b28242a6a1e27f9bb590646849594e7 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 27 Dec 2016 20:04:02 +0100 Subject: Update Mockito to 2.4.5 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index e24a1b2..4236a27 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -28,7 +28,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.3.9" + compile "org.mockito:mockito-core:2.4.5" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From cf0347810cce9906d23bddff5f3bdc1f7b22e25a Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Tue, 27 Dec 2016 20:19:29 +0100 Subject: Cleanup --- tmp.txt | 181 ---------------------------------------------------------------- 1 file changed, 181 deletions(-) delete mode 100644 tmp.txt diff --git a/tmp.txt b/tmp.txt deleted file mode 100644 index 171670e..0000000 --- a/tmp.txt +++ /dev/null @@ -1,181 +0,0 @@ -a1ea33b Update Dokka to 0.9.11 -e3344f4 Update Gradle wrapper to 3.2.1 -3c714eb Update Kotlin to 1.0.5-3 -8118f1a Update Mockito to 2.3.9 -327d431 Merge pull request #137 from nhaarman/release-1.0.1 -8c9e5d7 Merge branch 'master' into dev -e07e419 Update PULL_REQUEST_TEMPLATE.md -263344f Merge pull request #135 from nhaarman/handle-null-in-argumentmatcher -b77d969 Handle `null` in argument matchers. -543238f Merge pull request #131 from nhaarman/release-1.0.0 -ed6d30d Update tagging script -af1940c Update Mockito to 2.2.28 -0ba47f4 Update dokka plugin -04cd24d Merge pull request #130 from nhaarman/release-1.0.0-RC1 -5418cff Update README.md -559ffc5 Remove deprecated methods -dc4ab0a Update publishing -a734cde Test with Kotlin 1.1-M03 -7fb4bd9 Merge pull request #127 from nhaarman/release-0.12.2 -05a65ec Update Mockito to 2.2.22 -62f3170 Merge branch 'ghostbuster91-FeatureRequest_isAclassShouldReturnInstance' into dev -acde82f Change isA method to return instance of T -72279be Merge pull request #123 from nhaarman/release-0.12.1 -c974db0 Update Mockito to 2.2.17 -e6f6d2c Update Kotlin to 1.0.5-2 -b665264 Merge pull request #122 from nhaarman/inorder-lambda -59bf311 Add a lambda to inOrder() for easier verification -b50831b Fix release build config -ebc6147 Merge pull request #121 from nhaarman/release-0.12.0 -66d8249 Also test with Kotlin 1.1 -cdc34a0 Merge pull request #120 from nhaarman/cast-null -18ed580 Use `null as T` to create instances -ae1d863 Merge pull request #119 from nhaarman/clean-tests -ab1eb0d Use same test source for inline tests -2b31ed7 Merge branch 'master' into dev -57d0d8b Merge pull request #118 from nhaarman/improve-argumentcaptor -81a0996 Add value shortcuts to ArgumentCaptor -37f1717 Merge pull request #117 from nhaarman/nullable-eq -1eead3e Return passed value instead of trying to create an instance -a831657 Update Mockito to 2.2.15 -5f12032 Merge pull request #113 from rongi/patch-1 -e7ed7cb Update to Kotlin 1.0.5 -27c6bf6 Merge pull request #111 from nhaarman/release-0.11.0 -771f761 Merge pull request #110 from nhaarman/graciously_fail -c8fecf0 Try to use constructor when mocking fails -fa27978 Merge pull request #109 from nhaarman/nullable-mockstubbing -f353562 Accept nullable return types when stubbing -50a1b91 Merge pull request #108 from nhaarman/release-0.10.1 -c3f7e68 Merge pull request #107 from nhaarman/create-primitive-instance -0615231 Don't try to mock primitive/wrapper instances -494e7ca Merge pull request #105 from nhaarman/fix-generic-returntype-npe -113d9e9 Catch an NPE thrown by the Kotlin type checker in the Mockito library. -3b5c40a Merge pull request #102 from nhaarman/release-0.10.0 -6af0904 Update Mockito to 2.2.9 -287065a Merge pull request #101 from nhaarman/skip-optional-parameters -42cee20 Don't count optional parameters when trying to find an easy constructor -e43ccea Merge pull request #100 from nhaarman/nullable-argumentcaptor -086d482 Add `nullableArgumentCaptor` to be able to work with lists of nullables -7b6c5b7 Merge branch 'desilvai-dev' into dev -395e578 Fixed infinite loop caused by 'copy constructors' invoked by createInstance. The fix is to skip all constructors that take in parameters with same type as the object we are trying to build. -24108bd Merge pull request #98 from nhaarman/release-0.9.0 -6126454 Update version badge -5a31910 Merge pull request #97 from nhaarman/deprecation-levels -63826bf Upgrade deprecation levels to ERROR -3db9e21 Update Mockito to 2.2.6 -5884adc Merge pull request #96 from nhaarman/dokka -fb74552 Use dokka do generate docs -f165976 Merge pull request #95 from nhaarman/publish-to-maven-central -8e083ad Publish to Maven Central instead of Bintray -5878bbe Merge pull request #93 from nhaarman/release-0.8.0 -d556691 Update Mockito to 2.2.1 -6ee75f7 Merge pull request #92 from nhaarman/create-array-instance -0b43d0b Use the java class' name to create an array instance -cd16b04 Merge pull request #91 from nhaarman/improve-captors -80dbefd Improve argument captors -fd98501 Merge pull request #90 from nhaarman/ongoingstubbing-dothrow -94b3c65 Added doThrow methods to OngoingStubbing -85bb5e4 Merge branch 'desilvai-dev' into dev -6965414 Fix compatibility with mock-maker-inline for mocking final classes -ea6e64c Merge pull request #85 from nhaarman/release-0.7.0 -36e3dd5 Merge pull request #84 from nhaarman/fix-createinstance-from-lambda -1d65fc0 Strip methods from file identifiers. -1025568 Merge pull request #83 from nhaarman/stubbing-mock-reference -0c3e137 Provide mock instance to stubbing method in mock() -3f73e27 Merge pull request #82 from nhaarman/mockito-rc2 -e549d8d Update Mockito dependency to 2.1.0 -0886485 Update Mockito dependency to RC2 -2d724bc Merge pull request #74 from viniciussoares/dev -f2ed004 Upgrade Kotlin to 1.0.4. -9c4234e Merge pull request #73 from nhaarman/release-0.6.2 -cf06555 Merge pull request #72 from nhaarman/any-or-null -9351840 Include `anyOrNull()` -3d64888 Merge pull request #71 from jpshelley/mockito-2.1.0-RC.1 -6862ea5 update to RC.1 -4c09ebc Merge branch 'master' into dev -f18d86e Merge pull request #70 from nhaarman/release-0.6.1 -650e293 Update README.md -f291e71 Merge pull request #69 from nhaarman/argforwhich -9a3b7de Introduce argForWhich() as an alias for argThat() -8d53bad Merge pull request #68 from nhaarman/fix-anyarrayofnullables -9507a20 Make anyArray() accept nullable types. -7dcebc9 Stop. Sending me. Emails. -c029a13 Merge pull request #67 from nhaarman/deprecate-deprecated-methods -400b1cc Deprecate methods that are deprecated in Mockito. -c06d37f Merge pull request #64 from nhaarman/fix-simplest-constructor -18be968 Improve `easiestConstructor()` to sort by parameters size. -855c14b Update gradle wrapper to 3.0 -58013d8 Update dependencies -6110a90 Update Mockito version to 2.1.0-beta.125 -6cf8557 Update README.md -d07a2c9 Merge pull request #59 from nhaarman/release-0.6.0 -2a2ed98 Merge pull request #58 from nhaarman/mock-stubbing -ecfaf58 Add infix modifiers to doReturn methods -2d4eef9 Accept a stubbing lambda in mock() -84fb7e0 Merge branch 'master' into dev -49d59a6 Merge pull request #55 from sghill/mockito-2.0.99-beta -2f94f52 Upgrade Mockito to 2.0.99-beta -a6f8604 Merge pull request #53 from nhaarman/release-0.5.2 -51385ca Added an example to the Readme on Argument Captors. -6a521ea Make `doReturn` accept null values. -c3e6182 Specify explicit return types for Mockito calls. -6867394 Merge pull request #50 from Zoltu/patch-1 -25fb19c Upgrade Kotlin version to 1.0.3. -e1de1f6 Makes `mock` return non-null types. -bb4ac76 Merge pull request #43 from nhaarman/release-0.5.1 -8e6ab15 Update gradle wrapper version -c400381 Merge pull request #42 from hamen/master -c44c15a Update Kotlin version -62cd94f Merge pull request #38 from nhaarman/release-0.5.0 -aa49bde Merge pull request #23 from nhaarman/instance-creators -f765a31 Use instance creators only from single test file. -17dadf9 Update README.md -cddcf7f Introduce instance creators. -4cbd876 Merge pull request #36 from nhaarman/release-0.4.1 -abfc083 Update dependencies -772d0d9 Merge pull request #33 from nhaarman/release-0.4.0 -1322b92 Update dependencies -55e9a3c Merge pull request #30 from nhaarman/release-0.3.1 -df0c3f6 Remove Travis-CI cache -d4e73a9 Merge pull request #29 from nhaarman/uncheckedmock-interceptor -c8d9f68 Unset the MockitoInterceptor for unchecked mocks. -129f9e6 Merge pull request #28 from nhaarman/create-class-objects -ae4ab17 Account for Class when creating instances. -a013a48 Merge pull request #19 from nhaarman/avoid-array-parameters -ea0263d Avoid constructors with an array as a parameter. -48fc1aa Merge pull request #16 from nhaarman/release-0.3.0 -fc95068 Merge branch 'dev' of https://github.com/codeborne/mockito-kotlin into codeborne-dev -5105493 Include more static Mockito methods -9238c4c add simpler capture() method with lambda -ce93783 Merge pull request #12 from codeborne/master -66e3be5 add simplified ArgumentCaptor support -1262c19 add deep stubs test -f6f142a add spy stubbing tests -0efd093 Added PR template -624b7c4 Merge pull request #10 from ViFork/master -334d471 add missing imports -76be5d0 add more missing Mockito methods, especially to be used with spies -40bf7c6 changed kotlin version to 1.0.0 -7cafd23 Merge pull request #7 from nhaarman/release-0.2.0 -8b93c66 Update Kotlin to rc-1036 -8488479 Merge pull request #6 from nhaarman/release-0.1.6 -1d9a588 Use smallest constructor -37ded6f Merge pull request #5 from nhaarman/release-0.1.5 -8157be6 Support Boolean -0665c25 Merge pull request #4 from nhaarman/release-0.1.4 -a873fa7 Support private classes -0cc78ba Merge pull request #3 from nhaarman/release-0.1.3 -65d6a5f Support object instances -c4bde0f Merge pull request #2 from nhaarman/release-0.1.2 -9856798 Proper license -9f1df2d Make sure 'eq' does not return null -90f6598 Merge branch 'master' into dev -b40c9ae Update README.md -ad964f7 Update README.md -92bb350 Cache Travis dependencies -886cad6 Proper version names -139d47c Proper version names -78505b7 Merge pull request #1 from nhaarman/release-0.1.1 -b5a4e87 Support enums -b113029 Upload to Bintray -2f9603a Initial commit -- cgit v1.2.3 From ce6bf8a2b5082da8255c4216fd39449904d3600b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 21 Jan 2017 14:14:02 +0100 Subject: Update Dokka --- gradle/wrapper/gradle-wrapper.properties | 2 +- mockito-kotlin/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cf73567..bf0524d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 4236a27..98d1ab9 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -13,7 +13,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.11" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.13" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" } -- cgit v1.2.3 From 8e8fe3af463d470b07e67ce7bcaa9a1e27c54db4 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 21 Jan 2017 14:17:51 +0100 Subject: Update Mockito to 2.6.5 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 98d1ab9..79fbdd3 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -28,7 +28,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.4.5" + compile "org.mockito:mockito-core:2.6.5" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 1d39f6f56a7f61f570bf76d1f459e1f0151c7fff Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 21 Jan 2017 14:18:26 +0100 Subject: Update Expect.kt to 0.6.2 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 79fbdd3..3179962 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -32,7 +32,7 @@ dependencies { /* Tests */ testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:0.6.0" + testCompile "com.nhaarman:expect.kt:0.6.2" } dokka { -- cgit v1.2.3 From a804d1e996017b609ae5df0a97253b4011c24ce1 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 21 Jan 2017 14:26:47 +0100 Subject: Test with Mockito 1.1.0-beta-18 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36ba395..3a873be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ matrix: - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.6 - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1-M04 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.0-beta-18 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.6 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1-M04 + env: TERM=dumb KOTLIN_VERSION=1.1.0-beta-18 env: -- cgit v1.2.3 From f9f3abc42dd55a991ffa2699f8d0987a68947d90 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 19 Jan 2017 22:20:06 +0100 Subject: Add regression tests in preparation for settings API --- mockito-kotlin/src/test/kotlin/test/Classes.kt | 11 ++ mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 165 ++++++++++++++++++++- 2 files changed, 174 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/test/kotlin/test/Classes.kt b/mockito-kotlin/src/test/kotlin/test/Classes.kt index 58dc995..3476585 100644 --- a/mockito-kotlin/src/test/kotlin/test/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/test/Classes.kt @@ -60,6 +60,17 @@ interface Methods { fun stringResult(s: String): String fun nullableStringResult(): String? fun builderMethod(): Methods + + fun nonDefaultReturnType(): ExtraInterface +} + +interface ExtraInterface + +abstract class ThrowingConstructor { + + constructor() { + error("Error in constructor") + } } interface GenericMethods { diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 65670f2..ace45f9 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -5,8 +5,15 @@ import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail import com.nhaarman.mockito_kotlin.* import org.junit.Test +import org.mockito.Mockito import org.mockito.exceptions.base.MockitoAssertionError +import org.mockito.exceptions.verification.WantedButNotInvoked +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode.BASIC import java.io.IOException +import java.io.PrintStream +import java.io.Serializable + /* * The MIT License @@ -244,8 +251,8 @@ class MockitoTest : TestBase() { val mock = mock() doAnswer { "Test" } - .whenever(mock) - .stringResult() + .whenever(mock) + .stringResult() expect(mock.stringResult()).toBe("Test") } @@ -479,6 +486,160 @@ class MockitoTest : TestBase() { } } + @Test + fun mock_withCustomName() { + /* Given */ + val mock = mock("myName") + + /* Expect */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withCustomDefaultAnswer() { + /* Given */ + val mock = mock(Mockito.RETURNS_SELF) + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun mock_withCustomDefaultAnswer_parameterName() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_SELF) + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun mock_withSettings_extraInterfaces() { + /* Given */ + val mock = mock( + withSettings().extraInterfaces(ExtraInterface::class.java) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettings_name() { + /* Given */ + val mock = mock( + withSettings().name("myName") + ) + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettings_defaultAnswer() { + /* Given */ + val mock = mock( + withSettings().defaultAnswer(Mockito.RETURNS_MOCKS) + ) + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mock_withSettings_serializable() { + /* Given */ + val mock = mock( + withSettings().serializable() + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettings_serializableMode() { + /* Given */ + val mock = mock( + withSettings().serializable(BASIC) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettings_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock( + withSettings().verboseLogging() + ) + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch(e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mock_withSettings_invocationListeners() { + /* Given */ + var bool = false + val mock = mock( + withSettings().invocationListeners(InvocationListener { bool = true }) + ) + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mock_withSettings_stubOnly() { + /* Given */ + val mock = mock( + withSettings().stubOnly() + ) + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettings_useConstructor() { + /* Expect */ + expectErrorWithMessage("Unable to create mock instance of type") on { + mock( + withSettings().useConstructor() + ) + } + } + @Test fun stubbingTwiceWithArgumentMatchers() { /* When */ -- cgit v1.2.3 From 26a139fdffab393cd470a3ebaad00660edf89990 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 19 Jan 2017 21:14:17 +0100 Subject: Enhance settings API --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 109 +++++++++-- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 216 ++++++++++++++++++++- 2 files changed, 305 insertions(+), 20 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index c64a514..379d218 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -26,16 +26,16 @@ package com.nhaarman.mockito_kotlin import com.nhaarman.mockito_kotlin.createinstance.createInstance -import org.mockito.InOrder -import org.mockito.MockSettings -import org.mockito.MockingDetails -import org.mockito.Mockito +import org.mockito.* import org.mockito.invocation.InvocationOnMock +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode import org.mockito.stubbing.Answer import org.mockito.stubbing.OngoingStubbing import org.mockito.stubbing.Stubber import org.mockito.verification.VerificationMode import org.mockito.verification.VerificationWithTimeout +import kotlin.DeprecationLevel.WARNING import kotlin.reflect.KClass fun after(millis: Long) = Mockito.after(millis) @@ -74,7 +74,7 @@ inline fun argForWhich(noinline predicate: T.() -> Boolean) = * * @param predicate A function that returns `true` when given [T] matches the predicate. */ -inline fun argWhere(noinline predicate: (T) -> Boolean) = argThat(predicate) +inline fun argWhere(noinline predicate: (T) -> Boolean) = argThat(predicate) /** * For usage with verification only. @@ -120,16 +120,70 @@ inline fun isA(): T = Mockito.isA(T::class.java) ?: createInst fun isNotNull(): T? = Mockito.isNotNull() fun isNull(): T? = Mockito.isNull() -inline fun mock(): T = Mockito.mock(T::class.java)!! -inline fun mock(defaultAnswer: Answer): T = Mockito.mock(T::class.java, defaultAnswer)!! +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null +): T = Mockito.mock(T::class.java, withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance +))!! + +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null, + stubbing: KStubbing.(T) -> Unit +): T = Mockito.mock(T::class.java, withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance +)).apply { + KStubbing(this).stubbing(this) +}!! + +@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(defaultAnswer = a)"), level = WARNING) +inline fun mock(a: Answer): T = mock(defaultAnswer = a) + +@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(name = s)"), level = WARNING) +inline fun mock(s: String): T = mock(name = s) + +@Suppress("DeprecatedCallableAddReplaceWith") +@Deprecated("Use mock() with optional arguments instead.", level = WARNING) inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! -inline fun mock(s: String): T = Mockito.mock(T::class.java, s)!! - -inline fun mock(stubbing: KStubbing.(T) -> Unit): T { - return mock().apply { - KStubbing(this).stubbing(this) - } -} class KStubbing(private val mock: T) { fun on(methodCall: R) = Mockito.`when`(methodCall) @@ -193,4 +247,29 @@ fun verifyNoMoreInteractions(vararg mocks: T) = Mockito.verifyNoMoreInteract fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(*mocks) fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! -fun withSettings(): MockSettings = Mockito.withSettings()!! + +fun withSettings( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null +): MockSettings = Mockito.withSettings().apply { + extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } + name?.let { name(it) } + spiedInstance?.let { spiedInstance(it) } + defaultAnswer?.let { defaultAnswer(it) } + if (serializable) serializable() + serializableMode?.let { serializable(it) } + if (verboseLogging) verboseLogging() + invocationListeners?.let { invocationListeners(*it) } + if (stubOnly) stubOnly() + if (useConstructor) useConstructor() + outerInstance?.let { outerInstance(it) } +} diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index ace45f9..ce57d62 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -6,6 +6,7 @@ import com.nhaarman.expect.fail import com.nhaarman.mockito_kotlin.* import org.junit.Test import org.mockito.Mockito +import org.mockito.Mockito.RETURNS_MOCKS import org.mockito.exceptions.base.MockitoAssertionError import org.mockito.exceptions.verification.WantedButNotInvoked import org.mockito.listeners.InvocationListener @@ -40,6 +41,7 @@ import java.io.Serializable * THE SOFTWARE. */ +@Suppress("DEPRECATION") class MockitoTest : TestBase() { @Test @@ -415,7 +417,7 @@ class MockitoTest : TestBase() { @Test fun testMockStubbing_doThrow() { /* Given */ - val mock = mock { mock -> + val mock = mock { on { builderMethod() } doThrow IllegalArgumentException() } @@ -430,7 +432,7 @@ class MockitoTest : TestBase() { @Test fun testMockStubbing_doThrowClass() { /* Given */ - val mock = mock { mock -> + val mock = mock { on { builderMethod() } doThrow IllegalArgumentException::class } @@ -445,7 +447,7 @@ class MockitoTest : TestBase() { @Test fun testMockStubbing_doThrowVarargs() { /* Given */ - val mock = mock { mock -> + val mock = mock { on { builderMethod() }.doThrow(IllegalArgumentException(), UnsupportedOperationException()) } @@ -467,7 +469,7 @@ class MockitoTest : TestBase() { @Test fun testMockStubbing_doThrowClassVarargs() { /* Given */ - val mock = mock { mock -> + val mock = mock { on { builderMethod() }.doThrow(IllegalArgumentException::class, UnsupportedOperationException::class) } @@ -549,7 +551,7 @@ class MockitoTest : TestBase() { fun mock_withSettings_defaultAnswer() { /* Given */ val mock = mock( - withSettings().defaultAnswer(Mockito.RETURNS_MOCKS) + withSettings().defaultAnswer(RETURNS_MOCKS) ) /* When */ @@ -640,6 +642,210 @@ class MockitoTest : TestBase() { } } + @Test + fun mock_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock( + extraInterfaces = arrayOf(ExtraInterface::class) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = RETURNS_MOCKS) + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mock_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch(e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mock_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mock_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + + @Test + fun mockStubbing_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock(extraInterfaces = arrayOf(ExtraInterface::class)) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") {} + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = RETURNS_MOCKS) {} + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mockStubbing_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) {} + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch(e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mockStubbing_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) {} + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mockStubbing_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) {} + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + @Test fun stubbingTwiceWithArgumentMatchers() { /* When */ -- cgit v1.2.3 From 45e6ce9e8bc3fbdf2f082711d505eab787ae85b2 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 11 Feb 2017 18:48:43 +0100 Subject: Add doAnswer to OngoingStubbing --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 2 ++ mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 28 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 379d218..07e2017 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -224,6 +224,8 @@ fun OngoingStubbing.doThrow(t: Throwable, vararg ts: Throwable): OngoingS infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing = thenThrow(t.java) fun OngoingStubbing.doThrow(t: KClass, vararg ts: KClass): OngoingStubbing = thenThrow(t.java, *ts.map { it.java }.toTypedArray()) +infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing = thenAnswer(answer) + fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! fun never(): VerificationMode = Mockito.never()!! fun notNull(): T? = Mockito.notNull() diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index ce57d62..237a224 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -488,6 +488,34 @@ class MockitoTest : TestBase() { } } + @Test + fun testMockStubbing_doAnswer() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testMockStubbing_doAnswer_withArgument() { + /* Given */ + val mock = mock { + on { stringResult(any()) } doAnswer { "${it.arguments[0]}-result" } + } + + /* When */ + val result = mock.stringResult("argument") + + /* Then */ + expect(result).toBe("argument-result") + } + @Test fun mock_withCustomName() { /* Given */ -- cgit v1.2.3 From 19969dffd3b7fdf210e1acaa998c5402d8dd0f00 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 11 Feb 2017 18:53:07 +0100 Subject: Update Mockito to 2.7.5 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 3179962..8debd61 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -28,7 +28,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.6.5" + compile "org.mockito:mockito-core:2.7.5" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From f5e093353dba59adc3bd5d10fb5bca9242e03678 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 11 Feb 2017 18:54:08 +0100 Subject: Update Gradle versions plugin to 0.14.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4bda747..f4da836 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.github.ben-manes.versions' version '0.13.0' + id 'com.github.ben-manes.versions' version '0.14.0' } apply from: 'gradle/scripts/tagging.gradle' -- cgit v1.2.3 From 5723b535971f1a8ecae93cb7b7034bee41ce49e8 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 11 Feb 2017 18:55:32 +0100 Subject: Test with Kotlin 1.1.0-beta-38 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a873be..3010e25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ matrix: - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.6 - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.0-beta-18 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.0-beta-38 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.6 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1.0-beta-18 + env: TERM=dumb KOTLIN_VERSION=1.1.0-beta-38 env: -- cgit v1.2.3 From 5a5fa35f76c12668c0432eef432d0e320bfcf12a Mon Sep 17 00:00:00 2001 From: pawel bochenski Date: Thu, 30 Mar 2017 15:15:53 +0200 Subject: Added stub extension function with this method one can define mock for class val someMock = mock() and then define stubs in test someMock.stub { on { something } doReturn somethingElse } It is useful when some tests reuse mock object but with different stubbing --- mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 07e2017..6d62267 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -175,6 +175,8 @@ inline fun mock( KStubbing(this).stubbing(this) }!! +inline fun T.stub(stubbing: KStubbing.(T) -> Unit) = this.apply { KStubbing(this).stubbing(this) } + @Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(defaultAnswer = a)"), level = WARNING) inline fun mock(a: Answer): T = mock(defaultAnswer = a) -- cgit v1.2.3 From 3349ebdae3ad467bca13d06511e54b62a606b929 Mon Sep 17 00:00:00 2001 From: pawel bochenski Date: Sat, 1 Apr 2017 11:37:08 +0200 Subject: added regression test --- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 237a224..d5055a7 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -516,6 +516,41 @@ class MockitoTest : TestBase() { expect(result).toBe("argument-result") } + @Test + fun testMockStubbingAfterCreatingMock() { + val mock = mock() + + //create stub after creation of mock + mock.stub { + on { stringResult() } doReturn "result" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOverrideDefaultStub() { + /* Given mock with stub */ + val mock = mock { + on { stringResult() } doReturn "result1" + } + + /* override stub */ + mock.stub { + on { stringResult() } doReturn "result2" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result2") + } + @Test fun mock_withCustomName() { /* Given */ -- cgit v1.2.3 From b6471b4a5b5cf03989fe11e9d572645b0401dc3c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 1 Apr 2017 19:29:15 +0200 Subject: Update Kotlin to 1.0.7 --- .travis.yml | 4 ++-- mockito-kotlin/build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3010e25..f4a5611 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,11 +5,11 @@ language: java matrix: include: - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.6 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.0-beta-38 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.0.6 + env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.1.0-beta-38 diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 8debd61..9059635 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: './publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.6' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.7' repositories { mavenCentral() -- cgit v1.2.3 From a52ae865d89ab50f804fc4938f44bdcaeb4e5754 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 1 Apr 2017 19:31:22 +0200 Subject: Test with Kotlin 1.1.1 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f4a5611..b42990a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ matrix: - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.0-beta-38 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.1 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1.0-beta-38 + env: TERM=dumb KOTLIN_VERSION=1.1.1 env: -- cgit v1.2.3 From a9a61afb9291081913ab93c4c6c4a23e9e31e638 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 1 Apr 2017 19:30:29 +0200 Subject: Update Mockito to 2.7.21 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 9059635..a9e473d 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -28,7 +28,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.7.5" + compile "org.mockito:mockito-core:2.7.21" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 76872e8807b4207d29036af2eeef615fbb2b336e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Jun 2017 15:02:03 +0200 Subject: Make `same` return non-null type --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 2 +- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 24 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index 6d62267..e53e993 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -236,7 +236,7 @@ fun refEq(value: T, vararg excludeFields: String): T? = Mockito.refEq(value, fun reset(vararg mocks: T) = Mockito.reset(*mocks) -fun same(value: T): T? = Mockito.same(value) ?: value +fun same(value: T): T = Mockito.same(value) ?: value inline fun spy(): T = Mockito.spy(T::class.java)!! fun spy(value: T): T = Mockito.spy(value)!! diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index d5055a7..c897c93 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -983,4 +983,28 @@ class MockitoTest : TestBase() { 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)) + } + } } \ No newline at end of file -- cgit v1.2.3 From 6c29db1e6b35708648482ec727a40504e1879657 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Jun 2017 15:34:29 +0200 Subject: Update Kotlin test version to 1.1.2-4 --- .travis.yml | 4 ++-- mockito-kotlin/build.gradle | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b42990a..1b5ebbc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ matrix: - jdk: oraclejdk7 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - jdk: oraclejdk7 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.1 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.2-4 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1.1 + env: TERM=dumb KOTLIN_VERSION=1.1.2-4 env: diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index a9e473d..c0dc9c3 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -8,7 +8,6 @@ buildscript { repositories { mavenCentral() jcenter() - maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1' } } dependencies { @@ -22,7 +21,6 @@ buildscript { repositories { mavenCentral() jcenter() - maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1' } } dependencies { -- cgit v1.2.3 From 1251c2d0d1e98b9560e6c505ac2ce570bae11b2e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Jun 2017 15:35:21 +0200 Subject: Update Mockito to 2.8.9 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index c0dc9c3..f404a43 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -26,7 +26,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.7.21" + compile "org.mockito:mockito-core:2.8.9" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From d9aca8c3d29e0a839ed6d5057e8f7b3410370981 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Jun 2017 15:35:42 +0200 Subject: Update Dokka gradle plugin to 0.9.14 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index f404a43..0ddd6e2 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -12,7 +12,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.13" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.14" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" } -- cgit v1.2.3 From 0824392614eacc71942b8156038a1a5c2999285d Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Jun 2017 15:36:02 +0200 Subject: Update Gradle versions plugin to 0.15.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f4da836..92ed15c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.github.ben-manes.versions' version '0.14.0' + id 'com.github.ben-manes.versions' version '0.15.0' } apply from: 'gradle/scripts/tagging.gradle' -- cgit v1.2.3 From 5246ea78037a025f5ea35d574811def0d14f02a1 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Jun 2017 16:04:09 +0200 Subject: Update Travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b5ebbc..d590b98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,9 @@ language: java matrix: include: - - jdk: oraclejdk7 + - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - - jdk: oraclejdk7 + - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.2-4 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 -- cgit v1.2.3 From c34b487609d62b243ae26c1682302b0ff22c83f9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 3 Jun 2017 16:25:02 +0200 Subject: Create module to release a kt1.1 artifact --- README.md | 6 +++ mockito-kotlin-kt1.1/build.gradle | 42 ++++++++++++++++++ mockito-kotlin/build.gradle | 2 +- mockito-kotlin/publishing.gradle | 92 --------------------------------------- publishing.gradle | 92 +++++++++++++++++++++++++++++++++++++++ settings.gradle | 2 +- 6 files changed, 142 insertions(+), 94 deletions(-) create mode 100644 mockito-kotlin-kt1.1/build.gradle delete mode 100644 mockito-kotlin/publishing.gradle create mode 100644 publishing.gradle diff --git a/README.md b/README.md index 5a424b4..4d4096a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,12 @@ For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` wi testCompile "com.nhaarman:mockito-kotlin:x.x.x" ``` +If you use Kotlin 1.1, you can instead depend on the `mockito-kotlin-kt1.1` artifact. + +```groovy +testCompile "com.nhaarman:mockito-kotlin-kt1.1:x.x.x" +``` + ## Example A test using Mockito-Kotlin typically looks like the following: diff --git a/mockito-kotlin-kt1.1/build.gradle b/mockito-kotlin-kt1.1/build.gradle new file mode 100644 index 0000000..e3851d8 --- /dev/null +++ b/mockito-kotlin-kt1.1/build.gradle @@ -0,0 +1,42 @@ +apply plugin: 'kotlin' +apply from: '../publishing.gradle' +apply plugin: 'org.jetbrains.dokka' + +buildscript { + ext.kotlin_version = '1.1.2-4' + + repositories { + mavenCentral() + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.14" + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" + classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" + } +} + +repositories { + mavenCentral() + jcenter() +} + +dependencies { + compile project(':mockito-kotlin') + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" +} + +dokka { + outputFormat = 'html' + outputDirectory = "$buildDir/javadoc" + + linkMapping { + dir = "src/main/kotlin" + url = "https://github.com/nhaarman/mockito-kotlin/tree/master/mockito-kotlin/src/main/kotlin" + suffix = "#L" + } +} +javadoc.dependsOn dokka \ No newline at end of file diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 0ddd6e2..d9da782 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'kotlin' -apply from: './publishing.gradle' +apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { diff --git a/mockito-kotlin/publishing.gradle b/mockito-kotlin/publishing.gradle deleted file mode 100644 index c8841e1..0000000 --- a/mockito-kotlin/publishing.gradle +++ /dev/null @@ -1,92 +0,0 @@ -apply plugin: 'signing' -apply plugin: 'com.jfrog.bintray' -apply plugin: 'com.github.dcendents.android-maven' - -group = 'com.nhaarman' -version = rootProject.ext.versionName - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from 'build/javadoc' -} - -task sourcesJar(type: Jar) { - from sourceSets.main.allSource - classifier = 'sources' -} - -artifacts { - archives jar - - archives javadocJar - archives sourcesJar -} - -signing { - sign configurations.archives -} - -install { - repositories.mavenInstaller { - pom { - project { - name 'Mockito-Kotlin' - packaging 'jar' - description 'Using Mockito with Kotlin.' - url 'https://github.com/nhaarman/mockito-kotlin' - - scm { - url 'scm:git@github.com:nhaarman/mockito-kotlin.git' - connection 'scm:git@github.com:nhaarman/mockito-kotlin.git' - developerConnection 'scm:git@github.com:nhaarman/mockito-kotlin.git' - } - - licenses { - license { - name 'MIT' - url 'https://opensource.org/licenses/MIT' - distribution 'repo' - } - } - - developers { - developer { - id 'nhaarman' - name 'Niek Haarman' - } - } - } - } - } -} - -bintray { - user = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') - key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') - - configurations = ['archives'] - - publish = true - - pkg { - repo = 'maven' - name = 'Mockito-Kotlin' - licenses = ['MIT'] - vcsUrl = 'https://github.com/nhaarman/mockito-kotlin.git' - - version { - name = versionName - - gpg { - sign = true - } - - mavenCentralSync { - sync = true - user = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') - password = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') - close = '1' - } - } - } -} \ No newline at end of file diff --git a/publishing.gradle b/publishing.gradle new file mode 100644 index 0000000..c8841e1 --- /dev/null +++ b/publishing.gradle @@ -0,0 +1,92 @@ +apply plugin: 'signing' +apply plugin: 'com.jfrog.bintray' +apply plugin: 'com.github.dcendents.android-maven' + +group = 'com.nhaarman' +version = rootProject.ext.versionName + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from 'build/javadoc' +} + +task sourcesJar(type: Jar) { + from sourceSets.main.allSource + classifier = 'sources' +} + +artifacts { + archives jar + + archives javadocJar + archives sourcesJar +} + +signing { + sign configurations.archives +} + +install { + repositories.mavenInstaller { + pom { + project { + name 'Mockito-Kotlin' + packaging 'jar' + description 'Using Mockito with Kotlin.' + url 'https://github.com/nhaarman/mockito-kotlin' + + scm { + url 'scm:git@github.com:nhaarman/mockito-kotlin.git' + connection 'scm:git@github.com:nhaarman/mockito-kotlin.git' + developerConnection 'scm:git@github.com:nhaarman/mockito-kotlin.git' + } + + licenses { + license { + name 'MIT' + url 'https://opensource.org/licenses/MIT' + distribution 'repo' + } + } + + developers { + developer { + id 'nhaarman' + name 'Niek Haarman' + } + } + } + } + } +} + +bintray { + user = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') + key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') + + configurations = ['archives'] + + publish = true + + pkg { + repo = 'maven' + name = 'Mockito-Kotlin' + licenses = ['MIT'] + vcsUrl = 'https://github.com/nhaarman/mockito-kotlin.git' + + version { + name = versionName + + gpg { + sign = true + } + + mavenCentralSync { + sync = true + user = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') + password = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') + close = '1' + } + } + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 3e1090c..23d28d1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ include 'mockito-kotlin' - +include 'mockito-kotlin-kt1.1' -- cgit v1.2.3 From b1beb308cbb01aab26734971f90d7904454bca02 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 27 Sep 2017 14:27:58 +0200 Subject: Remove the mockito-kotlin-kt1.1 artifact Instead, users can explicitly depend on kotlin-reflect themselves: compile 'org.jetbrains.kotlin:kotlin-reflect:x.x.x' --- mockito-kotlin-kt1.1/build.gradle | 42 --------------------------------------- settings.gradle | 1 - 2 files changed, 43 deletions(-) delete mode 100644 mockito-kotlin-kt1.1/build.gradle diff --git a/mockito-kotlin-kt1.1/build.gradle b/mockito-kotlin-kt1.1/build.gradle deleted file mode 100644 index e3851d8..0000000 --- a/mockito-kotlin-kt1.1/build.gradle +++ /dev/null @@ -1,42 +0,0 @@ -apply plugin: 'kotlin' -apply from: '../publishing.gradle' -apply plugin: 'org.jetbrains.dokka' - -buildscript { - ext.kotlin_version = '1.1.2-4' - - repositories { - mavenCentral() - jcenter() - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.14" - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" - classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" - } -} - -repositories { - mavenCentral() - jcenter() -} - -dependencies { - compile project(':mockito-kotlin') - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" -} - -dokka { - outputFormat = 'html' - outputDirectory = "$buildDir/javadoc" - - linkMapping { - dir = "src/main/kotlin" - url = "https://github.com/nhaarman/mockito-kotlin/tree/master/mockito-kotlin/src/main/kotlin" - suffix = "#L" - } -} -javadoc.dependsOn dokka \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 23d28d1..4e54ed1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ include 'mockito-kotlin' -include 'mockito-kotlin-kt1.1' -- cgit v1.2.3 From ca8c1554e6db2908561485326bffb7d4d6566259 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 27 Sep 2017 14:32:45 +0200 Subject: Test using Kotlin 1.1.50 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d590b98..6853b3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.2-4 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.50 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1.2-4 + env: TERM=dumb KOTLIN_VERSION=1.1.50 env: -- cgit v1.2.3 From 7c94cc56e207eccfe985285f8132832430fce525 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 27 Sep 2017 14:35:29 +0200 Subject: Update Mockito to 2.10.0 --- mockito-kotlin/build.gradle | 2 +- .../mockito_kotlin/createinstance/InstanceCreator.kt | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index d9da782..c6c6ef7 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -26,7 +26,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.8.9" + compile "org.mockito:mockito-core:2.10.0" /* Tests */ testCompile "junit:junit:4.12" diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt index 7a8c5ae..8193cfb 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt @@ -2,8 +2,7 @@ package com.nhaarman.mockito_kotlin.createinstance import com.nhaarman.mockito_kotlin.MockitoKotlin import com.nhaarman.mockito_kotlin.MockitoKotlinException -import org.mockito.Answers -import org.mockito.internal.creation.MockSettingsImpl +import org.mockito.Mockito import org.mockito.internal.creation.bytebuddy.MockAccess import org.mockito.internal.util.MockUtil import java.lang.reflect.InvocationTargetException @@ -11,9 +10,7 @@ import java.lang.reflect.Modifier import java.lang.reflect.ParameterizedType import java.lang.reflect.Type import kotlin.reflect.* -import kotlin.reflect.jvm.isAccessible -import kotlin.reflect.jvm.javaType -import kotlin.reflect.jvm.jvmName +import kotlin.reflect.jvm.* import java.lang.reflect.Array as JavaArray internal class InstanceCreator() : NonNullProvider { @@ -174,9 +171,11 @@ internal class InstanceCreator() : NonNullProvider { */ @Suppress("UNCHECKED_CAST") fun Class.uncheckedMock(): T { - val impl = MockSettingsImpl().defaultAnswer(Answers.RETURNS_DEFAULTS) as MockSettingsImpl - val creationSettings = impl.confirm(this) - return MockUtil.createMock(creationSettings).apply { + val settings = Mockito.withSettings() + .defaultAnswer(Mockito.RETURNS_DEFAULTS) + .build(this) + + return MockUtil.createMock(settings).apply { (this as? MockAccess)?.mockitoInterceptor = null } } -- cgit v1.2.3 From 5da16bdd2a6e070afece69151349e5d2d9cb8ce9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 27 Sep 2017 14:35:45 +0200 Subject: Update Dokka gradle plugin to 0.9.15 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index c6c6ef7..39fd77a 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -12,7 +12,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.14" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.15" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" } -- cgit v1.2.3 From a25512a25f2c771d0028ac5646d2b787a904ed0a Mon Sep 17 00:00:00 2001 From: "Matthew S. Runo" Date: Tue, 11 Jul 2017 14:18:10 -0700 Subject: Use non-deprecated version of constructor to set RETURNS_DEEP_STUBS --- mockito-kotlin/src/test/kotlin/test/MockTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/src/test/kotlin/test/MockTest.kt b/mockito-kotlin/src/test/kotlin/test/MockTest.kt index 2073399..6f5dbe2 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockTest.kt @@ -81,7 +81,7 @@ class MockTest : TestBase() { @Test fun deepStubs() { - val cal: Calendar = mock(RETURNS_DEEP_STUBS) + val cal: Calendar = mock(defaultAnswer = RETURNS_DEEP_STUBS) whenever(cal.time.time).thenReturn(123L) expect(cal.time.time).toBe(123L) } -- cgit v1.2.3 From 1e496d6e6952f03c32827a2b2b01f9b6825569ee Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 27 Sep 2017 14:57:02 +0200 Subject: Update README --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 4d4096a..5a424b4 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,6 @@ For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` wi testCompile "com.nhaarman:mockito-kotlin:x.x.x" ``` -If you use Kotlin 1.1, you can instead depend on the `mockito-kotlin-kt1.1` artifact. - -```groovy -testCompile "com.nhaarman:mockito-kotlin-kt1.1:x.x.x" -``` - ## Example A test using Mockito-Kotlin typically looks like the following: -- cgit v1.2.3 From fdeccbd8cf0c2fc703e3e9642f49567fb7b41604 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 25 Nov 2017 15:58:06 +0100 Subject: Update Gradle versions plugin to 0.17.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 92ed15c..dc7a2d2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.github.ben-manes.versions' version '0.15.0' + id 'com.github.ben-manes.versions' version '0.17.0' } apply from: 'gradle/scripts/tagging.gradle' -- cgit v1.2.3 From 601f606f50433f2fd84e096b41b1b0f6c6fedabc Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 25 Nov 2017 15:58:19 +0100 Subject: Update Gradle wrapper to 4.3.1 --- gradle/wrapper/gradle-wrapper.jar | Bin 52271 -> 54208 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 74 +++++++------ gradlew.bat | 174 +++++++++++++++---------------- 4 files changed, 127 insertions(+), 125 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 30d399d..16f2083 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bf0524d..8dccdd6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Jan 20 23:10:29 CET 2016 +#Sat Nov 25 15:58:11 CET 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-bin.zip diff --git a/gradlew b/gradlew index 91a7e26..4453cce 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,12 +6,30 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282..e95643d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,90 +1,84 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega -- cgit v1.2.3 From 9cd85a5486b44f7755b717efef74d4da391caa1b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 25 Nov 2017 15:58:57 +0100 Subject: Update Mockito to 2.12.0 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 39fd77a..86e37c0 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -26,7 +26,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - compile "org.mockito:mockito-core:2.10.0" + compile "org.mockito:mockito-core:2.12.0" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From fcfd7b15e9b7977b43aa16e307038ffe2c751499 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 25 Nov 2017 15:59:19 +0100 Subject: Update Gradle bintray plugin to 1.8.0 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 86e37c0..5846e5c 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -13,7 +13,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.15" - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3" + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0" classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" } } -- cgit v1.2.3 From ffa7587c48d63211d984fa22c050d3364a380675 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 25 Nov 2017 16:00:49 +0100 Subject: Update maven gradle plugin to 2.0 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 5846e5c..60411e1 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -14,7 +14,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.15" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0" - classpath "com.github.dcendents:android-maven-gradle-plugin:1.5" + classpath "com.github.dcendents:android-maven-gradle-plugin:2.0" } } -- cgit v1.2.3 From 913b0e2962e65376afe5c01562836c264ae16be1 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 25 Nov 2017 16:02:01 +0100 Subject: Don't use deprecated Task.leftshift --- mockito-kotlin/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 60411e1..938cabb 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -46,7 +46,7 @@ dokka { javadoc.dependsOn dokka //Switch inline -task createTestResources << { +task createTestResources { def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") if (System.env.MOCK_MAKER != null) { logger.warn("! Using MockMaker ${System.env.MOCK_MAKER}") @@ -58,7 +58,7 @@ task createTestResources << { } } -task removeTestResources << { +task removeTestResources { def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") if (mockMakerFile.exists()) { mockMakerFile.delete() -- cgit v1.2.3 From 20a6519bc32ab003e5fb606baf6a722c31f7a85f Mon Sep 17 00:00:00 2001 From: Ramon Wirsch Date: Fri, 28 Jul 2017 18:10:27 +0200 Subject: Added VerifyScope, supporting a more spock like batch verification of calls --- .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 24 +++++++-- .../com/nhaarman/mockito_kotlin/VerifyScope.kt | 7 +++ mockito-kotlin/src/test/kotlin/test/VerifyTest.kt | 58 ++++++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/VerifyTest.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt index e53e993..e9d3b68 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt @@ -26,7 +26,11 @@ package com.nhaarman.mockito_kotlin import com.nhaarman.mockito_kotlin.createinstance.createInstance -import org.mockito.* +import org.mockito.InOrder +import org.mockito.Incubating +import org.mockito.MockSettings +import org.mockito.MockingDetails +import org.mockito.Mockito import org.mockito.invocation.InvocationOnMock import org.mockito.listeners.InvocationListener import org.mockito.mock.SerializableMode @@ -193,7 +197,7 @@ class KStubbing(private val mock: T) { fun onGeneric(methodCall: T.() -> R, c: KClass): OngoingStubbing { val r = try { mock.methodCall() - } catch(e: NullPointerException) { + } catch (e: NullPointerException) { // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a // null value for a non-nullable generic type. // We catch this NPE to return a valid instance. @@ -211,7 +215,7 @@ class KStubbing(private val mock: T) { fun on(methodCall: T.() -> R): OngoingStubbing { return try { Mockito.`when`(mock.methodCall()) - } catch(e: NullPointerException) { + } catch (e: NullPointerException) { throw MockitoKotlinException("NullPointerException thrown when stubbing. If you are trying to stub a generic method, try `onGeneric` instead.", e) } } @@ -277,3 +281,17 @@ fun withSettings( if (useConstructor) useConstructor() outerInstance?.let { outerInstance(it) } } + +/** + * Verify multiple calls on mock + * Supports an easier to read style of + * + * ``` + * verify(mock) { + * 2 * { call() } + * } + * ``` + */ +inline fun verify(mock: T, block: VerifyScope.() -> Unit) { + VerifyScope(mock).block() +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt new file mode 100644 index 0000000..80066d0 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt @@ -0,0 +1,7 @@ +package com.nhaarman.mockito_kotlin + +class VerifyScope(val mock: T) { + operator inline fun Int.times(call: T.() -> Unit) { + verify(mock, com.nhaarman.mockito_kotlin.times(this)).call() + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt b/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt new file mode 100644 index 0000000..321e51f --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt @@ -0,0 +1,58 @@ +package test + +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.mockito.exceptions.verification.TooLittleActualInvocations +import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent + +class VerifyTest : TestBase() { + + @Test + fun verify0Calls() { + val iface = mock() + + verify(iface) { + 0 * { call(any()) } + } + } + + @Test + fun verifyNCalls() { + val iface = mock() + + iface.call(42) + iface.call(42) + + verify(iface) { + 2 * { call(42) } + } + } + + @Test(expected = TooLittleActualInvocations::class) + fun verifyFailsWithWrongCount() { + val iface = mock() + + iface.call(0) + + verify(iface) { + 2 * { call(0) } + } + } + + @Test(expected = ArgumentsAreDifferent::class) + fun verifyFailsWithWrongArg() { + val iface = mock() + + iface.call(3) + + verify(iface) { + 1 * { call(0) } + } + } + + interface TestInterface { + fun call(arg: Int) + } +} \ No newline at end of file -- cgit v1.2.3 From faa626eb07549869130d34f903fba850acc849c5 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 30 Nov 2017 20:35:06 +0100 Subject: Remove InstanceCreator This allows for dropping the dependency on kotlin-reflect. It still existed as a backup, but seems not to be necessary. --- .gitignore | 1 + mockito-kotlin/build.gradle | 1 - .../com/nhaarman/mockito_kotlin/MockitoKotlin.kt | 85 --- .../createinstance/CreateInstance.kt | 4 +- .../createinstance/InstanceCreator.kt | 183 ------ .../createinstance/NonNullProvider.kt | 24 +- .../mockito_kotlin/createinstance/NullCaster.kt | 1 + .../test/createinstance/InstanceCreatorTest.kt | 621 --------------------- .../test/createinstance/NonNullProviderImplTest.kt | 77 --- .../kotlin/test/inline/UsingMockMakerInlineTest.kt | 48 +- 10 files changed, 11 insertions(+), 1034 deletions(-) delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt diff --git a/.gitignore b/.gitignore index be8403e..647ddbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .gradle build/ +out/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 938cabb..e32d9b1 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -25,7 +25,6 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "org.mockito:mockito-core:2.12.0" /* Tests */ diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt deleted file mode 100644 index 6c07cf6..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlin.kt +++ /dev/null @@ -1,85 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -import java.util.* -import kotlin.reflect.KClass - -class MockitoKotlin { - - companion object { - - /** - * Maps KClasses to functions that can create an instance of that KClass. - */ - private val creators: MutableMap, MutableList Any>>> = HashMap() - - /** - * Registers a function to be called when an instance of T is necessary. - */ - inline fun registerInstanceCreator(noinline creator: () -> T) = registerInstanceCreator(T::class, creator) - - /** - * Registers a function to be called when an instance of T is necessary. - */ - fun registerInstanceCreator(kClass: KClass, creator: () -> T) { - val element = Error().stackTrace[1] - - creators.getOrPut(kClass) { ArrayList Any>>() } - .add(element.toFileIdentifier() to creator) - } - - /** - * Unregisters an instance creator. - */ - inline fun unregisterInstanceCreator() = unregisterInstanceCreator(T::class) - - /** - * Unregisters an instance creator. - */ - fun unregisterInstanceCreator(kClass: KClass) = creators.remove(kClass) - - /** - * Clears al instance creators. - */ - fun resetInstanceCreators() = creators.clear() - - internal fun instanceCreator(kClass: KClass): (() -> Any)? { - val stacktrace = Error().stackTrace.filterNot { - it.className.contains("com.nhaarman.mockito_kotlin") - }[0] - - return creators[kClass] - ?.filter { it.first == stacktrace.toFileIdentifier() } - ?.firstOrNull() - ?.second - } - - private fun StackTraceElement.toFileIdentifier() = "$fileName$className".let { - if (it.contains("$")) it.substring(0..it.indexOf("$") - 1) else it - } - } -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt index 48b4719..a8df08b 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt @@ -30,7 +30,7 @@ import java.lang.reflect.Array as JavaArray inline fun createInstance(): T - = createInstance(T::class) + = createInstance(T::class) fun createInstance(kClass: KClass): T - = nonNullProvider().createInstance(kClass) + = NonNullProvider.create().createInstance(kClass) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt deleted file mode 100644 index 8193cfb..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/InstanceCreator.kt +++ /dev/null @@ -1,183 +0,0 @@ -package com.nhaarman.mockito_kotlin.createinstance - -import com.nhaarman.mockito_kotlin.MockitoKotlin -import com.nhaarman.mockito_kotlin.MockitoKotlinException -import org.mockito.Mockito -import org.mockito.internal.creation.bytebuddy.MockAccess -import org.mockito.internal.util.MockUtil -import java.lang.reflect.InvocationTargetException -import java.lang.reflect.Modifier -import java.lang.reflect.ParameterizedType -import java.lang.reflect.Type -import kotlin.reflect.* -import kotlin.reflect.jvm.* -import java.lang.reflect.Array as JavaArray - -internal class InstanceCreator() : NonNullProvider { - - override fun createInstance(kClass: KClass): T { - var cause: Throwable? = null - - @Suppress("UNCHECKED_CAST") - return MockitoKotlin.instanceCreator(kClass)?.invoke() as T? ?: - try { - when { - kClass.hasObjectInstance() -> kClass.objectInstance!! - kClass.isPrimitive() -> kClass.toDefaultPrimitiveValue() - kClass.isEnum() -> kClass.java.enumConstants.first() - kClass.isArray() -> kClass.toArrayInstance() - kClass.isClassObject() -> kClass.toClassObject() - kClass.isMockable() -> try { - kClass.java.uncheckedMock() - } catch(e: Throwable) { - cause = e - kClass.easiestConstructor().newInstance() - } - else -> kClass.easiestConstructor().newInstance() - } - } catch(e: Exception) { - if (e is MockitoKotlinException) throw e - - cause?.let { - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") - (e as java.lang.Throwable).initCause(it) - } - throw MockitoKotlinException("Could not create an instance for $kClass.", e) - } - } - - /** - * Tries to find the easiest constructor which it can instantiate. - */ - private fun KClass.easiestConstructor(): KFunction { - return constructors - .sortedBy { it.parameters.withoutOptionalParameters().size } - .withoutParametersOfType(this.defaultType) - .withoutArrayParameters() - .firstOrNull() ?: constructors.sortedBy { it.parameters.withoutOptionalParameters().size } - .withoutParametersOfType(this.defaultType) - .first() - } - - private fun List>.withoutArrayParameters() = filter { - it.parameters.filter { parameter -> parameter.type.toString().toLowerCase().contains("array") }.isEmpty() - } - - /** - * Filters out functions with the given type. - * This is especially useful to avoid infinite loops where constructors - * accepting a parameter of their own type, e.g. 'copy constructors'. - */ - private fun List>.withoutParametersOfType(type: KType) = filter { - it.parameters.filter { it.type == type }.isEmpty() - } - - private fun List.withoutOptionalParameters() = filterNot { it.isOptional } - - @Suppress("SENSELESS_COMPARISON") - private fun KClass<*>.hasObjectInstance() = objectInstance != null - - private fun KClass<*>.isMockable(): Boolean { - return !Modifier.isFinal(java.modifiers) || mockMakerInlineEnabled() - } - - private fun KClass<*>.isEnum() = java.isEnum - private fun KClass<*>.isArray() = java.isArray - private fun KClass<*>.isClassObject() = jvmName.equals("java.lang.Class") - private fun KClass<*>.isPrimitive() = - java.isPrimitive || !defaultType.isMarkedNullable && simpleName in arrayOf( - "Boolean", - "Byte", - "Short", - "Int", - "Double", - "Float", - "Long", - "String" - ) - - @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") - private fun KClass.toDefaultPrimitiveValue(): T { - return when (simpleName) { - "Boolean" -> true - "Byte" -> 0.toByte() - "Short" -> 0.toShort() - "Int" -> 0 - "Double" -> 0.0 - "Float" -> 0f - "Long" -> 0 - "String" -> "" - else -> throw UnsupportedOperationException("Cannot create default primitive for $simpleName.") - } as T - } - - @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") - private fun KClass.toArrayInstance(): T { - return when (simpleName) { - "ByteArray" -> byteArrayOf() - "ShortArray" -> shortArrayOf() - "IntArray" -> intArrayOf() - "LongArray" -> longArrayOf() - "DoubleArray" -> doubleArrayOf() - "FloatArray" -> floatArrayOf() - else -> { - val name = java.name.drop(2).dropLast(1) - return JavaArray.newInstance(Class.forName(name), 0) as T - } - } as T - } - - @Suppress("UNCHECKED_CAST") - private fun KClass.toClassObject(): T { - return Class.forName("java.lang.Object") as T - } - - private fun KFunction.newInstance(): T { - try { - isAccessible = true - return callBy(parameters.withoutOptionalParameters().associate { - it to it.type.createNullableInstance() - }) - } catch(e: InvocationTargetException) { - throw MockitoKotlinException( - """ - - Could not create an instance of class ${this.returnType}, because of an error with the following message: - - "${e.cause?.message}" - - Try registering an instance creator yourself, using MockitoKotlin.registerInstanceCreator<${this.returnType}> {...}.""", - e.cause - ) - } - } - - @Suppress("UNCHECKED_CAST") - private fun KType.createNullableInstance(): T? { - if (isMarkedNullable) { - return null - } - - val javaType: Type = javaType - return when (javaType) { - is ParameterizedType -> (javaType.rawType as Class).uncheckedMock() - is Class<*> -> createInstance((javaType as Class).kotlin) - else -> null - } - } - - /** - * Creates a mock instance of given class, without modifying or checking any internal Mockito state. - */ - @Suppress("UNCHECKED_CAST") - fun Class.uncheckedMock(): T { - val settings = Mockito.withSettings() - .defaultAnswer(Mockito.RETURNS_DEFAULTS) - .build(this) - - return MockUtil.createMock(settings).apply { - (this as? MockAccess)?.mockitoInterceptor = null - } - } -} - diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt index 15cb03e..b45a2a0 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt @@ -6,29 +6,9 @@ import java.lang.reflect.Array as JavaArray interface NonNullProvider { fun createInstance(kClass: KClass): T -} - -fun nonNullProvider(): NonNullProvider = NonNullProviderImpl(listOf(NullCaster(), InstanceCreator())) -internal class NonNullProviderImpl( - private val nonNullProviders: List -) : NonNullProvider { - - override fun createInstance(kClass: KClass): T { - return firstNonErroring( - nonNullProviders.map { { it.createInstance(kClass) } } - ) - } + companion object Factory { - private fun firstNonErroring(functions: List<() -> T>): T { - var error: Throwable? = null - functions.forEach { f -> - try { - return f() - } catch(e: Throwable) { - error = e - } - } - throw error ?: IllegalStateException() + fun create(): NonNullProvider = NullCaster() } } diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt index 6cd38c7..2cd263d 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt @@ -14,5 +14,6 @@ internal class NullCaster : NonNullProvider { return castNull() } + @Suppress("UNCHECKED_CAST") private fun castNull(): T = null as T } diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt deleted file mode 100644 index 8407727..0000000 --- a/mockito-kotlin/src/test/kotlin/test/createinstance/InstanceCreatorTest.kt +++ /dev/null @@ -1,621 +0,0 @@ -package test.createinstance - -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockito_kotlin.MockitoKotlin -import com.nhaarman.mockito_kotlin.any -import com.nhaarman.mockito_kotlin.createinstance.InstanceCreator -import com.nhaarman.mockito_kotlin.doReturn -import com.nhaarman.mockito_kotlin.mock -import org.junit.After -import org.junit.Test -import test.Closed -import test.Open -import test.TestBase -import java.util.* -import kotlin.reflect.KClass - -class InstanceCreatorTest : TestBase() { - - private val instanceCreator = InstanceCreator() - - private inline fun createInstance() = instanceCreator.createInstance(T::class) - - @After - fun teardown() { - MockitoKotlin.resetInstanceCreators() - } - - @Test - fun byte() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun short() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun int() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun long() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(0) - } - - @Test - fun double() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBeIn(-0.000001..0.000001) - } - - @Test - fun float() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBeIn(-0.000001f..0.000001f) - } - - @Test - fun boolean() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(true) - } - - @Test - fun string() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe("") - } - - @Test - fun byteArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun shortArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun intArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun longArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun doubleArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun floatArray() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun classArray_usingAny() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toBeInstanceOf>() - } - - @Test - fun closedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun closedClass_withOpenParameter() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun closedClass_withClosedParameter() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun singleParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun twoParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun threeParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun fourParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun fiveParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun sixParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun sevenParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedSingleParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedTwoParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedThreeParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedFourParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedFiveParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedSixParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nestedSevenParameterizedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun parameterizedClass() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nullableParameterClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun stringList() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun enum() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(MyEnum.VALUE) - } - - @Test - fun unit() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(Unit) - } - - @Test - fun privateClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun classObject() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun kClassObject() { - /* When */ - val result = createInstance>() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun uuid() { - /** - * The UUID class has a single-argument constructor that expects an array with some specific contents. - * We avoid these types of constructors by calling another constructor, if available. - * In this case, UUID(Long, Long). - */ - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(UUID(0, 0)) - } - - @Test - fun registeredInstanceCreator() { - /* Given */ - MockitoKotlin.registerInstanceCreator { ForbiddenConstructor(2) } - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun failedConstructor_throwsDescriptiveError() { - expectErrorWithMessage("Could not create an instance of class") on { - createInstance() - } - } - - @Test - fun defaultEmptyConstructor_takesSimplestConstructor() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - /** - * Bug: When the copy constructor is selected, we end up with an infinite - * loop. Instead, we want to select a constructor that doesn't - * take in a parameter with the same type as the one we are building. - * - * GIVEN a class with a copy constructor (in the case of the bug, the copy - * constructor has to be selected, so it must have fewer parameters - * than all other constructors) - * WHEN we make an instance of the given class - * THEN we expect that the new, non-null instance will be created without - * an exception - */ - @Test - fun copyConstructorDoesNotCauseException() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun optionalParametersAreSkippedWhenSorting() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun defaultValuesAreUsedWithOptionalParameters() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result.first).toBe(1) - expect(result.second).toBe(2) - } - - @Test - fun sealedClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun sealedClassMember() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun register() { - /* Given */ - val closed = Closed() - MockitoKotlin.registerInstanceCreator { closed } - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toBe(closed) - } - - @Test - fun unregister() { - /* Given */ - val closed = Closed() - MockitoKotlin.registerInstanceCreator { closed } - MockitoKotlin.unregisterInstanceCreator() - - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeTheSameAs(closed) - } - - @Test - fun usingInstanceCreatorInsideLambda() { - MockitoKotlin.registerInstanceCreator { InstanceCreatorTest.ForbiddenConstructor(2) } - - mock { - on { doSomething(any()) } doReturn "" - } - } - - interface TestClass { - - fun doSomething(c: InstanceCreatorTest.ForbiddenConstructor): String - } - - private class PrivateClass private constructor(val data: String) - - class ClosedClass - class ClosedParameterizedClass(val open: Open) - class ClosedClosedParameterizedClass(val closed: ClosedParameterizedClass) - - class SingleParameterClass(val first: Byte) - class TwoParameterClass(val first: Byte, val second: Short) - class ThreeParameterClass(val first: Byte, val second: Short, val third: Int) - class FourParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double) - class FiveParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float) - class SixParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long) - class SevenParameterClass(val first: Byte, val second: Short, val third: Int, val fourth: Double, val fifth: Float, val sixth: Long, val seventh: String) - - class NestedSingleParameterClass(val nested: SingleParameterClass) - class NestedTwoParameterClass(val nested: TwoParameterClass) - class NestedThreeParameterClass(val nested: ThreeParameterClass) - class NestedFourParameterClass(val nested: FourParameterClass) - class NestedFiveParameterClass(val nested: FiveParameterClass) - class NestedSixParameterClass(val nested: SixParameterClass) - class NestedSevenParameterClass(val nested: SevenParameterClass) - - class ParameterizedClass(val t: T) - class NullableParameterClass(val s: String?) - - class ForbiddenConstructor { - - constructor() { - throw AssertionError("Forbidden.") - } - - constructor(@Suppress("UNUSED_PARAMETER") value: Int) { - } - } - - class WithDefaultEmptyConstructor() { - constructor(@Suppress("UNUSED_PARAMETER") c: ForbiddenConstructor) : this() - } - - /** - * Bug: When the copy constructor is selected, then create instance gets - * into an infinite loop. We should never use the copy constructor in - * createInstance. - */ - data class WithCopyConstructor private constructor(val x: String, - val y: String) { - constructor(other: WithCopyConstructor) : this(other.x, other.y) - } - - /** - * A class that uses default parameters, but with a constructor without parameters that fails. - * This is to make sure default parameters are not counted when sorting by parameter size. - */ - class WithDefaultParameters constructor(val first: Int = 1, val second: Int = 2) { - - constructor(@Suppress("UNUSED_PARAMETER") first: Int) : this() { - error("Should not be called") - } - } - - enum class MyEnum { VALUE, ANOTHER_VALUE } -} - -sealed class MySealedClass { - class MySealedClassMember : MySealedClass() -} diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt deleted file mode 100644 index 7527c61..0000000 --- a/mockito-kotlin/src/test/kotlin/test/createinstance/NonNullProviderImplTest.kt +++ /dev/null @@ -1,77 +0,0 @@ -package test.createinstance - -import com.nhaarman.mockito_kotlin.* -import com.nhaarman.mockito_kotlin.createinstance.NonNullProvider -import com.nhaarman.mockito_kotlin.createinstance.NonNullProviderImpl -import org.junit.Test -import test.TestBase - -class NonNullProviderImplTest : TestBase() { - - @Test(expected = IllegalStateException::class) - fun createInstance_withoutDelegates_throwsException() { - /* Given */ - val nonNullProvider = NonNullProviderImpl(emptyList()) - - /* When */ - nonNullProvider.createInstance(String::class) - } - - @Test - fun createInstance_withSingleDelegate_callsThatDelegate() { - /* Given */ - val delegate = mock() - val nonNullProvider = NonNullProviderImpl(listOf(delegate)) - - /* When */ - nonNullProvider.createInstance(String::class) - - /* Then */ - verify(delegate).createInstance(String::class) - } - - @Test(expected = UnsupportedOperationException::class) - fun createInstance_withSingleDelegateThatFails_throwsException() { - /* Given */ - val delegate = mock { - on { createInstance(any()) } doThrow UnsupportedOperationException() - } - val nonNullProvider = NonNullProviderImpl(listOf(delegate)) - - /* When */ - nonNullProvider.createInstance(String::class) - } - - @Test - fun createInstance_withTwoDelegates_doesNotCallSecondDelegate() { - /* Given */ - val delegate1 = mock() - val delegate2 = mock() - val nonNullProvider = NonNullProviderImpl(listOf(delegate1, delegate2)) - - /* When */ - nonNullProvider.createInstance(String::class) - - /* Then */ - verify(delegate1).createInstance(String::class) - verify(delegate2, never()).createInstance(String::class) - } - - @Test - fun createInstance_withTwoDelegates_firstDelegateFails_callsSecondDelegate() { - /* Given */ - val delegate1 = mock { - on { createInstance(any()) } doThrow UnsupportedOperationException() - } - val delegate2 = mock() - val nonNullProvider = NonNullProviderImpl(listOf(delegate1, delegate2)) - - /* When */ - nonNullProvider.createInstance(String::class) - - /* Then */ - verify(delegate1).createInstance(String::class) - verify(delegate2).createInstance(String::class) - } -} - diff --git a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt index 93c5f9f..2cd5c13 100644 --- a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt @@ -23,9 +23,12 @@ */ import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* -import com.nhaarman.mockito_kotlin.createinstance.InstanceCreator +import com.nhaarman.mockito_kotlin.any import com.nhaarman.mockito_kotlin.createinstance.mockMakerInlineEnabled +import com.nhaarman.mockito_kotlin.doReturn +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.verify +import com.nhaarman.mockito_kotlin.whenever import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test @@ -44,8 +47,6 @@ class UsingMockMakerInlineTest { } } - private inline fun createInstance() = InstanceCreator().createInstance(T::class) - @Before fun setup() { mockMakerInlineEnabled = null @@ -109,42 +110,6 @@ class UsingMockMakerInlineTest { } } - @Test - fun createPrimitiveInstance() { - /* When */ - val i = createInstance() - - /* Then */ - expect(i).toBe(0) - } - - @Test - fun createStringInstance() { - /* When */ - val s = createInstance() - - /* Then */ - expect(s).toBe("") - } - - @Test - fun sealedMemberClass() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun sealedClassMember() { - /* When */ - val result = createInstance() - - /* Then */ - expect(result).toNotBeNull() - } - interface Methods { fun throwableClass(t: ThrowableClass) @@ -152,7 +117,4 @@ class UsingMockMakerInlineTest { class ThrowableClass(cause: Throwable) : Throwable(cause) - sealed class MySealedClass { - class MySealedClassMember : MySealedClass() - } } -- cgit v1.2.3 From 2731365a59aa93492a45798c9466bb529ce230b1 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 30 Nov 2017 20:36:37 +0100 Subject: Test using Kotlin 1.2.0 --- .travis.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6853b3c..09a5879 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,15 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.50 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.61 + - jdk: oraclejdk8 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.0 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.1.50 + env: TERM=dumb KOTLIN_VERSION=1.1.61 + - jdk: oraclejdk8 + env: TERM=dumb KOTLIN_VERSION=1.2.0 env: -- cgit v1.2.3 From 2de53c622ebcd90ca0e89eaea6e53738cb7b6994 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 30 Nov 2017 22:36:54 +0100 Subject: Use spring-bintray-plugin for publishing --- RELEASING.md | 3 +- build.gradle | 11 ++++++ publishing.gradle | 102 +++++++++++++++--------------------------------------- 3 files changed, 39 insertions(+), 77 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 49f0d01..07e3973 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,6 +1,5 @@ To publish a release: - Tag the commit on master: `git tag -a x.x.x -m x.x.x && git push --tags` - - Execute the release process: `./gradlew clean test uploadArchives -PisRelease=true` - - Head to https://oss.sonatype.org/#stagingRepositories to close and release the deployment. + - Execute the release process: `./gradlew clean test mavenCentralSync -PisRelease=true` - Don't forget to publish the tag on Github with release notes :) \ No newline at end of file diff --git a/build.gradle b/build.gradle index dc7a2d2..6fd77d1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,14 @@ +buildscript { + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "io.spring.gradle:spring-bintray-plugin:0.9.0" + } +} + plugins { id 'com.github.ben-manes.versions' version '0.17.0' } diff --git a/publishing.gradle b/publishing.gradle index c8841e1..e0b166a 100644 --- a/publishing.gradle +++ b/publishing.gradle @@ -1,91 +1,43 @@ -apply plugin: 'signing' -apply plugin: 'com.jfrog.bintray' -apply plugin: 'com.github.dcendents.android-maven' +apply plugin: 'maven-publish' +apply plugin: "io.spring.bintray" -group = 'com.nhaarman' -version = rootProject.ext.versionName +bintray { + bintrayUser = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') + bintrayKey = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') + repo = 'maven' + org = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') + packageName = 'Mockito-Kotlin' + publication = 'mavenJava' + + licenses = ['MIT'] + ossrhUser = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') + ossrhPassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') + overrideOnUpload = false +} +bintray.gpgPassphrase = hasProperty('signing_password') ? signing_password : System.getenv('SIGNING_PASSWORD') task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from 'build/javadoc' } -task sourcesJar(type: Jar) { +task sourceJar(type: Jar) { from sourceSets.main.allSource - classifier = 'sources' -} - -artifacts { - archives jar - - archives javadocJar - archives sourcesJar -} - -signing { - sign configurations.archives -} - -install { - repositories.mavenInstaller { - pom { - project { - name 'Mockito-Kotlin' - packaging 'jar' - description 'Using Mockito with Kotlin.' - url 'https://github.com/nhaarman/mockito-kotlin' - - scm { - url 'scm:git@github.com:nhaarman/mockito-kotlin.git' - connection 'scm:git@github.com:nhaarman/mockito-kotlin.git' - developerConnection 'scm:git@github.com:nhaarman/mockito-kotlin.git' - } - - licenses { - license { - name 'MIT' - url 'https://opensource.org/licenses/MIT' - distribution 'repo' - } - } - - developers { - developer { - id 'nhaarman' - name 'Niek Haarman' - } - } - } - } - } } -bintray { - user = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') - key = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') - - configurations = ['archives'] - - publish = true - - pkg { - repo = 'maven' - name = 'Mockito-Kotlin' - licenses = ['MIT'] - vcsUrl = 'https://github.com/nhaarman/mockito-kotlin.git' +group = 'com.nhaarman' +version = rootProject.ext.versionName - version { - name = versionName +publishing { + publications { + mavenJava(MavenPublication) { + groupId 'com.nhaarman' + artifactId 'mockito-kotlin' - gpg { - sign = true - } + from components.java - mavenCentralSync { - sync = true - user = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') - password = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') - close = '1' + artifact sourceJar { + classifier "sources" } } } -- cgit v1.2.3 From 8b3cacbbac049851dffa340c3039a70b7b94bec6 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 30 Nov 2017 22:50:26 +0100 Subject: Update package and artifact info to mockitokotlin2 This follows Jake Wharton's guide for interoperability between major versions: http://jakewharton.com/java-interoperability-policy-for-major-version-updates/ --- .../com/nhaarman/mockito_kotlin/ArgumentCaptor.kt | 84 ------ .../com/nhaarman/mockito_kotlin/BDDMockito.kt | 13 - .../kotlin/com/nhaarman/mockito_kotlin/Mockito.kt | 297 --------------------- .../mockito_kotlin/MockitoKotlinException.kt | 28 -- .../kotlin/com/nhaarman/mockito_kotlin/Stubber.kt | 30 --- .../com/nhaarman/mockito_kotlin/VerifyScope.kt | 7 - .../createinstance/CreateInstance.kt | 36 --- .../mockito_kotlin/createinstance/MockMaker.kt | 10 - .../createinstance/NonNullProvider.kt | 14 - .../mockito_kotlin/createinstance/NullCaster.kt | 19 -- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 84 ++++++ .../com/nhaarman/mockitokotlin2/BDDMockito.kt | 13 + .../kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 297 +++++++++++++++++++++ .../mockitokotlin2/MockitoKotlinException.kt | 28 ++ .../kotlin/com/nhaarman/mockitokotlin2/Stubber.kt | 30 +++ .../com/nhaarman/mockitokotlin2/VerifyScope.kt | 7 + .../createinstance/CreateInstance.kt | 36 +++ .../mockitokotlin2/createinstance/MockMaker.kt | 10 + .../createinstance/NonNullProvider.kt | 14 + .../mockitokotlin2/createinstance/NullCaster.kt | 19 ++ .../src/test/kotlin/test/ArgumentCaptorTest.kt | 2 +- .../src/test/kotlin/test/BDDMockitoTest.kt | 2 +- mockito-kotlin/src/test/kotlin/test/EqTest.kt | 4 +- mockito-kotlin/src/test/kotlin/test/MockTest.kt | 4 +- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 2 +- mockito-kotlin/src/test/kotlin/test/SpyTest.kt | 3 +- mockito-kotlin/src/test/kotlin/test/TestBase.kt | 2 +- mockito-kotlin/src/test/kotlin/test/VerifyTest.kt | 6 +- .../kotlin/test/createinstance/NullCasterTest.kt | 2 +- .../kotlin/test/inline/UsingMockMakerInlineTest.kt | 12 +- publishing.gradle | 4 +- 31 files changed, 559 insertions(+), 560 deletions(-) delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt deleted file mode 100644 index 5b5004d..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/ArgumentCaptor.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -import com.nhaarman.mockito_kotlin.createinstance.createInstance -import org.mockito.ArgumentCaptor -import kotlin.reflect.KClass - -inline fun argumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) -inline fun nullableArgumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) - -inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() - -class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass<*>) { - - /** - * The first captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val firstValue: T - get() = captor.firstValue - - /** - * The second captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val secondValue: T - get() = captor.secondValue - - /** - * The third captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val thirdValue: T - get() = captor.thirdValue - - /** - * The last captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val lastValue: T - get() = captor.lastValue - - val allValues: List - get() = captor.allValues - - @Suppress("UNCHECKED_CAST") - fun capture(): T = captor.capture() ?: createInstance(tClass) as T -} - -val ArgumentCaptor.firstValue: T - get() = allValues[0] - -val ArgumentCaptor.secondValue: T - get() = allValues[1] - -val ArgumentCaptor.thirdValue: T - get() = allValues[2] - -val ArgumentCaptor.lastValue: T - get() = allValues.last() diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt deleted file mode 100644 index 203232d..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/BDDMockito.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.nhaarman.mockito_kotlin - -import org.mockito.BDDMockito - -fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing = BDDMockito.given(methodCall) -fun given(methodCall: () -> T) = given(methodCall()) - -fun then(mock: T): BDDMockito.Then = BDDMockito.then(mock) - -infix fun BDDMockito.BDDMyOngoingStubbing.willAnswer(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willAnswer { value() } -infix fun BDDMockito.BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willReturn(value()) -infix fun BDDMockito.BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing = willThrow(value()) - diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt deleted file mode 100644 index e9d3b68..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Mockito.kt +++ /dev/null @@ -1,297 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -import com.nhaarman.mockito_kotlin.createinstance.createInstance -import org.mockito.InOrder -import org.mockito.Incubating -import org.mockito.MockSettings -import org.mockito.MockingDetails -import org.mockito.Mockito -import org.mockito.invocation.InvocationOnMock -import org.mockito.listeners.InvocationListener -import org.mockito.mock.SerializableMode -import org.mockito.stubbing.Answer -import org.mockito.stubbing.OngoingStubbing -import org.mockito.stubbing.Stubber -import org.mockito.verification.VerificationMode -import org.mockito.verification.VerificationWithTimeout -import kotlin.DeprecationLevel.WARNING -import kotlin.reflect.KClass - -fun after(millis: Long) = Mockito.after(millis) - -/** Matches any object, excluding nulls. */ -inline fun any() = Mockito.any(T::class.java) ?: createInstance() - -/** Matches anything, including nulls. */ -inline fun anyOrNull(): T = Mockito.any() ?: createInstance() - -/** Matches any vararg object, including nulls. */ -inline fun anyVararg(): T = Mockito.any() ?: createInstance() - -/** Matches any array of type T. */ -inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. - */ -inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { arg -> arg?.predicate() ?: false } ?: createInstance(T::class) - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. - */ -inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate A function that returns `true` when given [T] matches the predicate. - */ -inline fun argWhere(noinline predicate: (T) -> Boolean) = argThat(predicate) - -/** - * For usage with verification only. - * - * For example: - * verify(myObject).doSomething(check { assertThat(it, is("Test")) }) - * - * @param predicate A function that performs actions to verify an argument [T]. - */ -inline fun check(noinline predicate: (T) -> Unit) = Mockito.argThat { arg -> - if (arg == null) error("""The argument passed to the predicate was null. - -If you are trying to verify an argument to be null, use `isNull()`. -If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. -""".trimIndent()) - predicate(arg) - true -} ?: createInstance(T::class) - -fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! -fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!! -fun atMost(maxNumberOfInvocations: Int): VerificationMode = Mockito.atMost(maxNumberOfInvocations)!! -fun calls(wantedNumberOfInvocations: Int): VerificationMode = Mockito.calls(wantedNumberOfInvocations)!! - -fun clearInvocations(vararg mocks: T) = Mockito.clearInvocations(*mocks) -fun description(description: String): VerificationMode = Mockito.description(description) - -fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber = Mockito.doAnswer { answer(it) }!! - -fun doCallRealMethod(): Stubber = Mockito.doCallRealMethod()!! -fun doNothing(): Stubber = Mockito.doNothing()!! -fun doReturn(value: Any?): Stubber = Mockito.doReturn(value)!! -fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber = Mockito.doReturn(toBeReturned, *toBeReturnedNext)!! -fun doThrow(toBeThrown: KClass): Stubber = Mockito.doThrow(toBeThrown.java)!! -fun doThrow(vararg toBeThrown: Throwable): Stubber = Mockito.doThrow(*toBeThrown)!! - -fun eq(value: T): T = Mockito.eq(value) ?: value -fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks)!! -fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! -fun inOrder(vararg mocks: Any, evaluation: InOrder.() -> Unit) = Mockito.inOrder(*mocks).evaluation() - -inline fun isA(): T = Mockito.isA(T::class.java) ?: createInstance() -fun isNotNull(): T? = Mockito.isNotNull() -fun isNull(): T? = Mockito.isNull() - -inline fun mock( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, - @Incubating outerInstance: Any? = null -): T = Mockito.mock(T::class.java, withSettings( - extraInterfaces = extraInterfaces, - name = name, - spiedInstance = spiedInstance, - defaultAnswer = defaultAnswer, - serializable = serializable, - serializableMode = serializableMode, - verboseLogging = verboseLogging, - invocationListeners = invocationListeners, - stubOnly = stubOnly, - useConstructor = useConstructor, - outerInstance = outerInstance -))!! - -inline fun mock( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, - @Incubating outerInstance: Any? = null, - stubbing: KStubbing.(T) -> Unit -): T = Mockito.mock(T::class.java, withSettings( - extraInterfaces = extraInterfaces, - name = name, - spiedInstance = spiedInstance, - defaultAnswer = defaultAnswer, - serializable = serializable, - serializableMode = serializableMode, - verboseLogging = verboseLogging, - invocationListeners = invocationListeners, - stubOnly = stubOnly, - useConstructor = useConstructor, - outerInstance = outerInstance -)).apply { - KStubbing(this).stubbing(this) -}!! - -inline fun T.stub(stubbing: KStubbing.(T) -> Unit) = this.apply { KStubbing(this).stubbing(this) } - -@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(defaultAnswer = a)"), level = WARNING) -inline fun mock(a: Answer): T = mock(defaultAnswer = a) - -@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(name = s)"), level = WARNING) -inline fun mock(s: String): T = mock(name = s) - -@Suppress("DeprecatedCallableAddReplaceWith") -@Deprecated("Use mock() with optional arguments instead.", level = WARNING) -inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! - -class KStubbing(private val mock: T) { - fun on(methodCall: R) = Mockito.`when`(methodCall) - - fun onGeneric(methodCall: T.() -> R, c: KClass): OngoingStubbing { - val r = try { - mock.methodCall() - } catch (e: NullPointerException) { - // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a - // null value for a non-nullable generic type. - // We catch this NPE to return a valid instance. - // The Mockito state has already been modified at this point to reflect - // the wanted changes. - createInstance(c) - } - return Mockito.`when`(r) - } - - inline fun onGeneric(noinline methodCall: T.() -> R): OngoingStubbing { - return onGeneric(methodCall, R::class) - } - - fun on(methodCall: T.() -> R): OngoingStubbing { - return try { - Mockito.`when`(mock.methodCall()) - } catch (e: NullPointerException) { - throw MockitoKotlinException("NullPointerException thrown when stubbing. If you are trying to stub a generic method, try `onGeneric` instead.", e) - } - } -} - -infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing = thenReturn(t) -fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing = thenReturn(t, *ts) -inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing = thenReturn(ts[0], *ts.drop(1).toTypedArray()) - -infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing = thenThrow(t) -fun OngoingStubbing.doThrow(t: Throwable, vararg ts: Throwable): OngoingStubbing = thenThrow(t, *ts) -infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing = thenThrow(t.java) -fun OngoingStubbing.doThrow(t: KClass, vararg ts: KClass): OngoingStubbing = thenThrow(t.java, *ts.map { it.java }.toTypedArray()) - -infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing = thenAnswer(answer) - -fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! -fun never(): VerificationMode = Mockito.never()!! -fun notNull(): T? = Mockito.notNull() -fun only(): VerificationMode = Mockito.only()!! -fun refEq(value: T, vararg excludeFields: String): T? = Mockito.refEq(value, *excludeFields) - -fun reset(vararg mocks: T) = Mockito.reset(*mocks) - -fun same(value: T): T = Mockito.same(value) ?: value - -inline fun spy(): T = Mockito.spy(T::class.java)!! -fun spy(value: T): T = Mockito.spy(value)!! - -fun timeout(millis: Long): VerificationWithTimeout = Mockito.timeout(millis)!! -fun times(numInvocations: Int): VerificationMode = Mockito.times(numInvocations)!! -fun validateMockitoUsage() = Mockito.validateMockitoUsage() - -fun verify(mock: T): T = Mockito.verify(mock)!! -fun verify(mock: T, mode: VerificationMode): T = Mockito.verify(mock, mode)!! -fun verifyNoMoreInteractions(vararg mocks: T) = Mockito.verifyNoMoreInteractions(*mocks) -fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(*mocks) - -fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! - -fun withSettings( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, - @Incubating outerInstance: Any? = null -): MockSettings = Mockito.withSettings().apply { - extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } - name?.let { name(it) } - spiedInstance?.let { spiedInstance(it) } - defaultAnswer?.let { defaultAnswer(it) } - if (serializable) serializable() - serializableMode?.let { serializable(it) } - if (verboseLogging) verboseLogging() - invocationListeners?.let { invocationListeners(*it) } - if (stubOnly) stubOnly() - if (useConstructor) useConstructor() - outerInstance?.let { outerInstance(it) } -} - -/** - * Verify multiple calls on mock - * Supports an easier to read style of - * - * ``` - * verify(mock) { - * 2 * { call() } - * } - * ``` - */ -inline fun verify(mock: T, block: VerifyScope.() -> Unit) { - VerifyScope(mock).block() -} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt deleted file mode 100644 index f183802..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/MockitoKotlinException.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -class MockitoKotlinException(message: String?, cause: Throwable?) : RuntimeException(message, cause) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt deleted file mode 100644 index cfb0bd5..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/Stubber.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin - -import org.mockito.stubbing.Stubber - -fun Stubber.whenever(mock: T) = `when`(mock) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt deleted file mode 100644 index 80066d0..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/VerifyScope.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.nhaarman.mockito_kotlin - -class VerifyScope(val mock: T) { - operator inline fun Int.times(call: T.() -> Unit) { - verify(mock, com.nhaarman.mockito_kotlin.times(this)).call() - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt deleted file mode 100644 index a8df08b..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/CreateInstance.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockito_kotlin.createinstance - -import kotlin.reflect.KClass -import java.lang.reflect.Array as JavaArray - - -inline fun createInstance(): T - = createInstance(T::class) - -fun createInstance(kClass: KClass): T - = NonNullProvider.create().createInstance(kClass) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt deleted file mode 100644 index bf18518..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/MockMaker.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.nhaarman.mockito_kotlin.createinstance - -import org.mockito.internal.configuration.plugins.Plugins -import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker - -internal var mockMakerInlineEnabled: Boolean? = null -internal fun mockMakerInlineEnabled(): Boolean { - return mockMakerInlineEnabled ?: - Plugins.getMockMaker() is InlineByteBuddyMockMaker -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt deleted file mode 100644 index b45a2a0..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NonNullProvider.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.nhaarman.mockito_kotlin.createinstance - -import kotlin.reflect.KClass -import java.lang.reflect.Array as JavaArray - -interface NonNullProvider { - - fun createInstance(kClass: KClass): T - - companion object Factory { - - fun create(): NonNullProvider = NullCaster() - } -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt deleted file mode 100644 index 2cd263d..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockito_kotlin/createinstance/NullCaster.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.nhaarman.mockito_kotlin.createinstance - -import kotlin.reflect.KClass - -/** - * Uses a quirk in the bytecode generated by Kotlin - * to cast [null] to a non-null type. - * - * See https://youtrack.jetbrains.com/issue/KT-8135. - */ -internal class NullCaster : NonNullProvider { - - override fun createInstance(kClass: KClass): T { - return castNull() - } - - @Suppress("UNCHECKED_CAST") - private fun castNull(): T = null as T -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt new file mode 100644 index 0000000..a25faeb --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt @@ -0,0 +1,84 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import com.nhaarman.mockitokotlin2.createinstance.createInstance +import org.mockito.ArgumentCaptor +import kotlin.reflect.KClass + +inline fun argumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) +inline fun nullableArgumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) + +inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() + +class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass<*>) { + + /** + * The first captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val firstValue: T + get() = captor.firstValue + + /** + * The second captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val secondValue: T + get() = captor.secondValue + + /** + * The third captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val thirdValue: T + get() = captor.thirdValue + + /** + * The last captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val lastValue: T + get() = captor.lastValue + + val allValues: List + get() = captor.allValues + + @Suppress("UNCHECKED_CAST") + fun capture(): T = captor.capture() ?: createInstance(tClass) as T +} + +val ArgumentCaptor.firstValue: T + get() = allValues[0] + +val ArgumentCaptor.secondValue: T + get() = allValues[1] + +val ArgumentCaptor.thirdValue: T + get() = allValues[2] + +val ArgumentCaptor.lastValue: T + get() = allValues.last() diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt new file mode 100644 index 0000000..e2771f9 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt @@ -0,0 +1,13 @@ +package com.nhaarman.mockitokotlin2 + +import org.mockito.BDDMockito + +fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing = BDDMockito.given(methodCall) +fun given(methodCall: () -> T) = given(methodCall()) + +fun then(mock: T): BDDMockito.Then = BDDMockito.then(mock) + +infix fun BDDMockito.BDDMyOngoingStubbing.willAnswer(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willAnswer { value() } +infix fun BDDMockito.BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willReturn(value()) +infix fun BDDMockito.BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing = willThrow(value()) + diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt new file mode 100644 index 0000000..7f474c7 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -0,0 +1,297 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import com.nhaarman.mockitokotlin2.createinstance.createInstance +import org.mockito.InOrder +import org.mockito.Incubating +import org.mockito.MockSettings +import org.mockito.MockingDetails +import org.mockito.Mockito +import org.mockito.invocation.InvocationOnMock +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode +import org.mockito.stubbing.Answer +import org.mockito.stubbing.OngoingStubbing +import org.mockito.stubbing.Stubber +import org.mockito.verification.VerificationMode +import org.mockito.verification.VerificationWithTimeout +import kotlin.DeprecationLevel.WARNING +import kotlin.reflect.KClass + +fun after(millis: Long) = Mockito.after(millis) + +/** Matches any object, excluding nulls. */ +inline fun any() = Mockito.any(T::class.java) ?: createInstance() + +/** Matches anything, including nulls. */ +inline fun anyOrNull(): T = Mockito.any() ?: createInstance() + +/** Matches any vararg object, including nulls. */ +inline fun anyVararg(): T = Mockito.any() ?: createInstance() + +/** Matches any array of type T. */ +inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ +inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { arg -> arg?.predicate() ?: false } ?: createInstance(T::class) + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ +inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate A function that returns `true` when given [T] matches the predicate. + */ +inline fun argWhere(noinline predicate: (T) -> Boolean) = argThat(predicate) + +/** + * For usage with verification only. + * + * For example: + * verify(myObject).doSomething(check { assertThat(it, is("Test")) }) + * + * @param predicate A function that performs actions to verify an argument [T]. + */ +inline fun check(noinline predicate: (T) -> Unit) = Mockito.argThat { arg -> + if (arg == null) error("""The argument passed to the predicate was null. + +If you are trying to verify an argument to be null, use `isNull()`. +If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. +""".trimIndent()) + predicate(arg) + true +} ?: createInstance(T::class) + +fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! +fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!! +fun atMost(maxNumberOfInvocations: Int): VerificationMode = Mockito.atMost(maxNumberOfInvocations)!! +fun calls(wantedNumberOfInvocations: Int): VerificationMode = Mockito.calls(wantedNumberOfInvocations)!! + +fun clearInvocations(vararg mocks: T) = Mockito.clearInvocations(*mocks) +fun description(description: String): VerificationMode = Mockito.description(description) + +fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber = Mockito.doAnswer { answer(it) }!! + +fun doCallRealMethod(): Stubber = Mockito.doCallRealMethod()!! +fun doNothing(): Stubber = Mockito.doNothing()!! +fun doReturn(value: Any?): Stubber = Mockito.doReturn(value)!! +fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber = Mockito.doReturn(toBeReturned, *toBeReturnedNext)!! +fun doThrow(toBeThrown: KClass): Stubber = Mockito.doThrow(toBeThrown.java)!! +fun doThrow(vararg toBeThrown: Throwable): Stubber = Mockito.doThrow(*toBeThrown)!! + +fun eq(value: T): T = Mockito.eq(value) ?: value +fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks)!! +fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! +fun inOrder(vararg mocks: Any, evaluation: InOrder.() -> Unit) = Mockito.inOrder(*mocks).evaluation() + +inline fun isA(): T = Mockito.isA(T::class.java) ?: createInstance() +fun isNotNull(): T? = Mockito.isNotNull() +fun isNull(): T? = Mockito.isNull() + +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null +): T = Mockito.mock(T::class.java, withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance +))!! + +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null, + stubbing: KStubbing.(T) -> Unit +): T = Mockito.mock(T::class.java, withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance +)).apply { + KStubbing(this).stubbing(this) +}!! + +inline fun T.stub(stubbing: KStubbing.(T) -> Unit) = this.apply { KStubbing(this).stubbing(this) } + +@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(defaultAnswer = a)"), level = WARNING) +inline fun mock(a: Answer): T = mock(defaultAnswer = a) + +@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(name = s)"), level = WARNING) +inline fun mock(s: String): T = mock(name = s) + +@Suppress("DeprecatedCallableAddReplaceWith") +@Deprecated("Use mock() with optional arguments instead.", level = WARNING) +inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! + +class KStubbing(private val mock: T) { + fun on(methodCall: R) = Mockito.`when`(methodCall) + + fun onGeneric(methodCall: T.() -> R, c: KClass): OngoingStubbing { + val r = try { + mock.methodCall() + } catch (e: NullPointerException) { + // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a + // null value for a non-nullable generic type. + // We catch this NPE to return a valid instance. + // The Mockito state has already been modified at this point to reflect + // the wanted changes. + createInstance(c) + } + return Mockito.`when`(r) + } + + inline fun onGeneric(noinline methodCall: T.() -> R): OngoingStubbing { + return onGeneric(methodCall, R::class) + } + + fun on(methodCall: T.() -> R): OngoingStubbing { + return try { + Mockito.`when`(mock.methodCall()) + } catch (e: NullPointerException) { + throw MockitoKotlinException("NullPointerException thrown when stubbing. If you are trying to stub a generic method, try `onGeneric` instead.", e) + } + } +} + +infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing = thenReturn(t) +fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing = thenReturn(t, *ts) +inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing = thenReturn(ts[0], *ts.drop(1).toTypedArray()) + +infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing = thenThrow(t) +fun OngoingStubbing.doThrow(t: Throwable, vararg ts: Throwable): OngoingStubbing = thenThrow(t, *ts) +infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing = thenThrow(t.java) +fun OngoingStubbing.doThrow(t: KClass, vararg ts: KClass): OngoingStubbing = thenThrow(t.java, *ts.map { it.java }.toTypedArray()) + +infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing = thenAnswer(answer) + +fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! +fun never(): VerificationMode = Mockito.never()!! +fun notNull(): T? = Mockito.notNull() +fun only(): VerificationMode = Mockito.only()!! +fun refEq(value: T, vararg excludeFields: String): T? = Mockito.refEq(value, *excludeFields) + +fun reset(vararg mocks: T) = Mockito.reset(*mocks) + +fun same(value: T): T = Mockito.same(value) ?: value + +inline fun spy(): T = Mockito.spy(T::class.java)!! +fun spy(value: T): T = Mockito.spy(value)!! + +fun timeout(millis: Long): VerificationWithTimeout = Mockito.timeout(millis)!! +fun times(numInvocations: Int): VerificationMode = Mockito.times(numInvocations)!! +fun validateMockitoUsage() = Mockito.validateMockitoUsage() + +fun verify(mock: T): T = Mockito.verify(mock)!! +fun verify(mock: T, mode: VerificationMode): T = Mockito.verify(mock, mode)!! +fun verifyNoMoreInteractions(vararg mocks: T) = Mockito.verifyNoMoreInteractions(*mocks) +fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(*mocks) + +fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! + +fun withSettings( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null +): MockSettings = Mockito.withSettings().apply { + extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } + name?.let { name(it) } + spiedInstance?.let { spiedInstance(it) } + defaultAnswer?.let { defaultAnswer(it) } + if (serializable) serializable() + serializableMode?.let { serializable(it) } + if (verboseLogging) verboseLogging() + invocationListeners?.let { invocationListeners(*it) } + if (stubOnly) stubOnly() + if (useConstructor) useConstructor() + outerInstance?.let { outerInstance(it) } +} + +/** + * Verify multiple calls on mock + * Supports an easier to read style of + * + * ``` + * verify(mock) { + * 2 * { call() } + * } + * ``` + */ +inline fun verify(mock: T, block: VerifyScope.() -> Unit) { + VerifyScope(mock).block() +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt new file mode 100644 index 0000000..ed18007 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt @@ -0,0 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +class MockitoKotlinException(message: String?, cause: Throwable?) : RuntimeException(message, cause) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt new file mode 100644 index 0000000..45b0d07 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt @@ -0,0 +1,30 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import org.mockito.stubbing.Stubber + +fun Stubber.whenever(mock: T) = `when`(mock) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt new file mode 100644 index 0000000..92b2ef0 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt @@ -0,0 +1,7 @@ +package com.nhaarman.mockitokotlin2 + +class VerifyScope(val mock: T) { + operator inline fun Int.times(call: T.() -> Unit) { + verify(mock, com.nhaarman.mockitokotlin2.times(this)).call() + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt new file mode 100644 index 0000000..ada8fef --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt @@ -0,0 +1,36 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2.createinstance + +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + + +inline fun createInstance(): T + = createInstance(T::class) + +fun createInstance(kClass: KClass): T + = NonNullProvider.create().createInstance(kClass) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt new file mode 100644 index 0000000..5cd3e11 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt @@ -0,0 +1,10 @@ +package com.nhaarman.mockitokotlin2.createinstance + +import org.mockito.internal.configuration.plugins.Plugins +import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker + +internal var mockMakerInlineEnabled: Boolean? = null +internal fun mockMakerInlineEnabled(): Boolean { + return mockMakerInlineEnabled ?: + Plugins.getMockMaker() is InlineByteBuddyMockMaker +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt new file mode 100644 index 0000000..1efc274 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt @@ -0,0 +1,14 @@ +package com.nhaarman.mockitokotlin2.createinstance + +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + +interface NonNullProvider { + + fun createInstance(kClass: KClass): T + + companion object Factory { + + fun create(): NonNullProvider = NullCaster() + } +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt new file mode 100644 index 0000000..6003f58 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt @@ -0,0 +1,19 @@ +package com.nhaarman.mockitokotlin2.createinstance + +import kotlin.reflect.KClass + +/** + * Uses a quirk in the bytecode generated by Kotlin + * to cast [null] to a non-null type. + * + * See https://youtrack.jetbrains.com/issue/KT-8135. + */ +internal class NullCaster : NonNullProvider { + + override fun createInstance(kClass: KClass): T { + return castNull() + } + + @Suppress("UNCHECKED_CAST") + private fun castNull(): T = null as T +} diff --git a/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt index f5b8562..551cc6b 100644 --- a/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt @@ -1,7 +1,7 @@ package test import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* +import com.nhaarman.mockitokotlin2.* import org.junit.Test import java.util.* diff --git a/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt index 1df2239..ded1462 100644 --- a/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt @@ -1,7 +1,7 @@ package test import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* +import com.nhaarman.mockitokotlin2.* import org.junit.Test class BDDMockitoTest { diff --git a/mockito-kotlin/src/test/kotlin/test/EqTest.kt b/mockito-kotlin/src/test/kotlin/test/EqTest.kt index 283bc3f..c070d95 100644 --- a/mockito-kotlin/src/test/kotlin/test/EqTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/EqTest.kt @@ -24,8 +24,8 @@ package test/* */ import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.eq -import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockitokotlin2.eq +import com.nhaarman.mockitokotlin2.mock import org.junit.After import org.junit.Before import org.junit.Test diff --git a/mockito-kotlin/src/test/kotlin/test/MockTest.kt b/mockito-kotlin/src/test/kotlin/test/MockTest.kt index 6f5dbe2..f17bbda 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockTest.kt @@ -24,8 +24,8 @@ package test/* */ import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.whenever +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.whenever import org.junit.Test import org.mockito.Mockito.RETURNS_DEEP_STUBS import java.util.* diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index c897c93..01d1446 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -3,7 +3,7 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail -import com.nhaarman.mockito_kotlin.* +import com.nhaarman.mockitokotlin2.* import org.junit.Test import org.mockito.Mockito import org.mockito.Mockito.RETURNS_MOCKS diff --git a/mockito-kotlin/src/test/kotlin/test/SpyTest.kt b/mockito-kotlin/src/test/kotlin/test/SpyTest.kt index ee1e2c6..877d6e3 100644 --- a/mockito-kotlin/src/test/kotlin/test/SpyTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/SpyTest.kt @@ -24,11 +24,10 @@ package test/* */ import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.* +import com.nhaarman.mockitokotlin2.* import org.junit.After import org.junit.Test import org.mockito.Mockito -import org.mockito.exceptions.base.MockitoException import java.util.* class SpyTest : TestBase() { diff --git a/mockito-kotlin/src/test/kotlin/test/TestBase.kt b/mockito-kotlin/src/test/kotlin/test/TestBase.kt index fb00e2b..f4b76e1 100644 --- a/mockito-kotlin/src/test/kotlin/test/TestBase.kt +++ b/mockito-kotlin/src/test/kotlin/test/TestBase.kt @@ -1,6 +1,6 @@ package test -import com.nhaarman.mockito_kotlin.createinstance.mockMakerInlineEnabled +import com.nhaarman.mockitokotlin2.createinstance.mockMakerInlineEnabled import org.junit.After import org.junit.Before diff --git a/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt b/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt index 321e51f..5807c8f 100644 --- a/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt @@ -1,8 +1,8 @@ package test -import com.nhaarman.mockito_kotlin.any -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.verify +import com.nhaarman.mockitokotlin2.any +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify import org.junit.Test import org.mockito.exceptions.verification.TooLittleActualInvocations import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt index 3a89f97..844728f 100644 --- a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt @@ -1,7 +1,7 @@ package test.createinstance import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.createinstance.NullCaster +import com.nhaarman.mockitokotlin2.createinstance.NullCaster import org.junit.Test import test.TestBase diff --git a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt index 2cd5c13..b346c0f 100644 --- a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt @@ -23,12 +23,12 @@ */ import com.nhaarman.expect.expect -import com.nhaarman.mockito_kotlin.any -import com.nhaarman.mockito_kotlin.createinstance.mockMakerInlineEnabled -import com.nhaarman.mockito_kotlin.doReturn -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.verify -import com.nhaarman.mockito_kotlin.whenever +import com.nhaarman.mockitokotlin2.any +import com.nhaarman.mockitokotlin2.createinstance.mockMakerInlineEnabled +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test diff --git a/publishing.gradle b/publishing.gradle index e0b166a..21039a7 100644 --- a/publishing.gradle +++ b/publishing.gradle @@ -25,13 +25,13 @@ task sourceJar(type: Jar) { from sourceSets.main.allSource } -group = 'com.nhaarman' +group = 'com.nhaarman.mockito-kotlin2' version = rootProject.ext.versionName publishing { publications { mavenJava(MavenPublication) { - groupId 'com.nhaarman' + groupId 'com.nhaarman.mockitokotlin2' artifactId 'mockito-kotlin' from components.java -- cgit v1.2.3 From 9ec377509ca74628a738d25eb35341fedc09f3ec Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 30 Nov 2017 23:00:21 +0100 Subject: Use internal package naming --- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 1 - .../com/nhaarman/mockitokotlin2/CreateInstance.kt | 37 ++++++++++++++++++++++ .../kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 1 - .../createinstance/CreateInstance.kt | 36 --------------------- .../mockitokotlin2/createinstance/MockMaker.kt | 10 ------ .../createinstance/NonNullProvider.kt | 14 -------- .../mockitokotlin2/createinstance/NullCaster.kt | 19 ----------- .../nhaarman/mockitokotlin2/internal/MockMaker.kt | 10 ++++++ .../mockitokotlin2/internal/NonNullProvider.kt | 14 ++++++++ .../nhaarman/mockitokotlin2/internal/NullCaster.kt | 19 +++++++++++ mockito-kotlin/src/test/kotlin/test/TestBase.kt | 2 +- .../kotlin/test/createinstance/NullCasterTest.kt | 2 +- .../kotlin/test/inline/UsingMockMakerInlineTest.kt | 2 +- 13 files changed, 83 insertions(+), 84 deletions(-) create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt index a25faeb..eaefb71 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt @@ -25,7 +25,6 @@ package com.nhaarman.mockitokotlin2 -import com.nhaarman.mockitokotlin2.createinstance.createInstance import org.mockito.ArgumentCaptor import kotlin.reflect.KClass diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt new file mode 100644 index 0000000..8cb0c32 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt @@ -0,0 +1,37 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import com.nhaarman.mockitokotlin2.internal.NonNullProvider +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + + +inline fun createInstance(): T + = createInstance(T::class) + +fun createInstance(kClass: KClass): T + = NonNullProvider.create().createInstance(kClass) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index 7f474c7..8989250 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -25,7 +25,6 @@ package com.nhaarman.mockitokotlin2 -import com.nhaarman.mockitokotlin2.createinstance.createInstance import org.mockito.InOrder import org.mockito.Incubating import org.mockito.MockSettings diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt deleted file mode 100644 index ada8fef..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/CreateInstance.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2.createinstance - -import kotlin.reflect.KClass -import java.lang.reflect.Array as JavaArray - - -inline fun createInstance(): T - = createInstance(T::class) - -fun createInstance(kClass: KClass): T - = NonNullProvider.create().createInstance(kClass) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt deleted file mode 100644 index 5cd3e11..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/MockMaker.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.nhaarman.mockitokotlin2.createinstance - -import org.mockito.internal.configuration.plugins.Plugins -import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker - -internal var mockMakerInlineEnabled: Boolean? = null -internal fun mockMakerInlineEnabled(): Boolean { - return mockMakerInlineEnabled ?: - Plugins.getMockMaker() is InlineByteBuddyMockMaker -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt deleted file mode 100644 index 1efc274..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NonNullProvider.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.nhaarman.mockitokotlin2.createinstance - -import kotlin.reflect.KClass -import java.lang.reflect.Array as JavaArray - -interface NonNullProvider { - - fun createInstance(kClass: KClass): T - - companion object Factory { - - fun create(): NonNullProvider = NullCaster() - } -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt deleted file mode 100644 index 6003f58..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/createinstance/NullCaster.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.nhaarman.mockitokotlin2.createinstance - -import kotlin.reflect.KClass - -/** - * Uses a quirk in the bytecode generated by Kotlin - * to cast [null] to a non-null type. - * - * See https://youtrack.jetbrains.com/issue/KT-8135. - */ -internal class NullCaster : NonNullProvider { - - override fun createInstance(kClass: KClass): T { - return castNull() - } - - @Suppress("UNCHECKED_CAST") - private fun castNull(): T = null as T -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt new file mode 100644 index 0000000..dc3e281 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt @@ -0,0 +1,10 @@ +package com.nhaarman.mockitokotlin2.internal + +import org.mockito.internal.configuration.plugins.Plugins +import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker + +internal var mockMakerInlineEnabled: Boolean? = null +internal fun mockMakerInlineEnabled(): Boolean { + return mockMakerInlineEnabled ?: + Plugins.getMockMaker() is InlineByteBuddyMockMaker +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt new file mode 100644 index 0000000..247a207 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt @@ -0,0 +1,14 @@ +package com.nhaarman.mockitokotlin2.internal + +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + +internal interface NonNullProvider { + + fun createInstance(kClass: KClass): T + + companion object Factory { + + fun create(): NonNullProvider = NullCaster() + } +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt new file mode 100644 index 0000000..7bb0479 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt @@ -0,0 +1,19 @@ +package com.nhaarman.mockitokotlin2.internal + +import kotlin.reflect.KClass + +/** + * Uses a quirk in the bytecode generated by Kotlin + * to cast [null] to a non-null type. + * + * See https://youtrack.jetbrains.com/issue/KT-8135. + */ +internal class NullCaster : NonNullProvider { + + override fun createInstance(kClass: KClass): T { + return castNull() + } + + @Suppress("UNCHECKED_CAST") + private fun castNull(): T = null as T +} diff --git a/mockito-kotlin/src/test/kotlin/test/TestBase.kt b/mockito-kotlin/src/test/kotlin/test/TestBase.kt index f4b76e1..1383ca3 100644 --- a/mockito-kotlin/src/test/kotlin/test/TestBase.kt +++ b/mockito-kotlin/src/test/kotlin/test/TestBase.kt @@ -1,6 +1,6 @@ package test -import com.nhaarman.mockitokotlin2.createinstance.mockMakerInlineEnabled +import com.nhaarman.mockitokotlin2.internal.mockMakerInlineEnabled import org.junit.After import org.junit.Before diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt index 844728f..16fb293 100644 --- a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt @@ -1,7 +1,7 @@ package test.createinstance import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.createinstance.NullCaster +import com.nhaarman.mockitokotlin2.internal.NullCaster import org.junit.Test import test.TestBase diff --git a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt index b346c0f..e8591b3 100644 --- a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt @@ -24,7 +24,7 @@ import com.nhaarman.expect.expect import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.createinstance.mockMakerInlineEnabled +import com.nhaarman.mockitokotlin2.internal.mockMakerInlineEnabled import com.nhaarman.mockitokotlin2.doReturn import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.verify -- cgit v1.2.3 From 2565ed411aa4432c6a85585e5cfafdf9d5ef9260 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 30 Nov 2017 23:04:26 +0100 Subject: Move properties out of 'bintray' block `hasProperty` does not seem to work inside this block --- publishing.gradle | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/publishing.gradle b/publishing.gradle index 21039a7..3473e72 100644 --- a/publishing.gradle +++ b/publishing.gradle @@ -1,19 +1,17 @@ apply plugin: 'maven-publish' apply plugin: "io.spring.bintray" -bintray { - bintrayUser = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') - bintrayKey = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') - repo = 'maven' - org = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') - packageName = 'Mockito-Kotlin' - publication = 'mavenJava' - - licenses = ['MIT'] - ossrhUser = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') - ossrhPassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') - overrideOnUpload = false -} +bintray.bintrayUser = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') +bintray.bintrayKey = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') +bintray.repo = 'maven' +bintray.org = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') +bintray.packageName = 'Mockito-Kotlin' +bintray.publication = 'mavenJava' + +bintray.licenses = ['MIT'] +bintray.ossrhUser = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') +bintray.ossrhPassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') +bintray.overrideOnUpload = false bintray.gpgPassphrase = hasProperty('signing_password') ? signing_password : System.getenv('SIGNING_PASSWORD') task javadocJar(type: Jar, dependsOn: javadoc) { -- cgit v1.2.3 From c4cb85e64ec5f27188a010c4a8626cfe20dae896 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 30 Nov 2017 23:40:43 +0100 Subject: Fix releasing to Maven Central --- RELEASING.md | 2 +- publishing.gradle | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index 07e3973..f1eb2d6 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,5 +1,5 @@ To publish a release: - Tag the commit on master: `git tag -a x.x.x -m x.x.x && git push --tags` - - Execute the release process: `./gradlew clean test mavenCentralSync -PisRelease=true` + - Execute the release process: `./gradlew clean test bintraySign mavenCentralSync -PisRelease=true` - Don't forget to publish the tag on Github with release notes :) \ No newline at end of file diff --git a/publishing.gradle b/publishing.gradle index 3473e72..cb03d87 100644 --- a/publishing.gradle +++ b/publishing.gradle @@ -37,6 +37,27 @@ publishing { artifact sourceJar { classifier "sources" } + + artifact javadocJar + + pom.withXml { + def root = asNode() + root.appendNode('name', 'Mockito-Kotlin') + root.appendNode('description', 'Using Mockito with Kotlin.') + root.appendNode('url', 'https://github.com/nhaarman/mockito-kotlin') + + def scm = root.appendNode('scm') + scm.appendNode('url', 'scm:git@github.com:nhaarman/mockito-kotlin.git') + + def licenses = root.appendNode('licenses') + def mitLicense = licenses.appendNode('license') + mitLicense.appendNode('name', 'MIT') + + def developers = root.appendNode('developers') + def nhaarman = developers.appendNode('developer') + nhaarman.appendNode('id', 'nhaarman') + nhaarman.appendNode('name', 'Niek Haarman') + } } } } \ No newline at end of file -- cgit v1.2.3 From 719cd29909c6eb8c37f2d0d5b238c651b52eeacb Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 3 Dec 2017 21:38:31 +0100 Subject: Implement OngoingStubbing.doAnswer(Answer) --- gradle/wrapper/gradle-wrapper.properties | 4 +- .../kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 1 + mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 46 ++++++++++++++-------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8dccdd6..1ae18be 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Nov 25 15:58:11 CET 2017 +#Sun Dec 03 21:34:47 CET 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-all.zip diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index 8989250..77986e2 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -230,6 +230,7 @@ infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubb fun OngoingStubbing.doThrow(t: KClass, vararg ts: KClass): OngoingStubbing = thenThrow(t.java, *ts.map { it.java }.toTypedArray()) infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing = thenAnswer(answer) +infix fun OngoingStubbing.doAnswer(answer: Answer): OngoingStubbing = thenAnswer(answer) fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! fun never(): VerificationMode = Mockito.never()!! diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 01d1446..eb613c7 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -1,8 +1,6 @@ package test -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.expect.fail +import com.nhaarman.expect.* import com.nhaarman.mockitokotlin2.* import org.junit.Test import org.mockito.Mockito @@ -11,9 +9,8 @@ import org.mockito.exceptions.base.MockitoAssertionError import org.mockito.exceptions.verification.WantedButNotInvoked import org.mockito.listeners.InvocationListener import org.mockito.mock.SerializableMode.BASIC -import java.io.IOException -import java.io.PrintStream -import java.io.Serializable +import org.mockito.stubbing.Answer +import java.io.* /* @@ -327,7 +324,7 @@ class MockitoTest : TestBase() { try { mock.go() throw AssertionError("Call should have thrown.") - } catch(e: IllegalStateException) { + } catch (e: IllegalStateException) { } } @@ -425,7 +422,7 @@ class MockitoTest : TestBase() { /* When */ mock.builderMethod() fail("No exception thrown") - } catch(e: IllegalArgumentException) { + } catch (e: IllegalArgumentException) { } } @@ -440,7 +437,7 @@ class MockitoTest : TestBase() { /* When */ mock.builderMethod() fail("No exception thrown") - } catch(e: IllegalArgumentException) { + } catch (e: IllegalArgumentException) { } } @@ -455,14 +452,14 @@ class MockitoTest : TestBase() { /* When */ mock.builderMethod() fail("No exception thrown") - } catch(e: IllegalArgumentException) { + } catch (e: IllegalArgumentException) { } try { /* When */ mock.builderMethod() fail("No exception thrown") - } catch(e: UnsupportedOperationException) { + } catch (e: UnsupportedOperationException) { } } @@ -477,19 +474,19 @@ class MockitoTest : TestBase() { /* When */ mock.builderMethod() fail("No exception thrown") - } catch(e: IllegalArgumentException) { + } catch (e: IllegalArgumentException) { } try { /* When */ mock.builderMethod() fail("No exception thrown") - } catch(e: UnsupportedOperationException) { + } catch (e: UnsupportedOperationException) { } } @Test - fun testMockStubbing_doAnswer() { + fun testMockStubbing_doAnswer_lambda() { /* Given */ val mock = mock { on { stringResult() } doAnswer { "result" } @@ -502,6 +499,21 @@ class MockitoTest : TestBase() { expect(result).toBe("result") } + @Test + fun testMockStubbing_doAnswer_instance() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer Answer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test fun testMockStubbing_doAnswer_withArgument() { /* Given */ @@ -659,7 +671,7 @@ class MockitoTest : TestBase() { /* When */ verify(mock).stringResult() fail("Expected an exception") - } catch(e: WantedButNotInvoked) { + } catch (e: WantedButNotInvoked) { /* Then */ verify(out).println("methods.stringResult();") } @@ -768,7 +780,7 @@ class MockitoTest : TestBase() { /* When */ verify(mock).stringResult() fail("Expected an exception") - } catch(e: WantedButNotInvoked) { + } catch (e: WantedButNotInvoked) { /* Then */ verify(out).println("methods.stringResult();") } @@ -869,7 +881,7 @@ class MockitoTest : TestBase() { /* When */ verify(mock).stringResult() fail("Expected an exception") - } catch(e: WantedButNotInvoked) { + } catch (e: WantedButNotInvoked) { /* Then */ verify(out).println("methods.stringResult();") } -- cgit v1.2.3 From 88187cd46272e72ead9b142342afe06724c71e8c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 3 Dec 2017 21:51:55 +0100 Subject: Improve error message on NPE in `on` --- .../kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 2 +- mockito-kotlin/src/test/kotlin/test/Classes.kt | 2 + mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 11 + .../src/test/kotlin/test/MockitoTest.kt.orig | 1036 ++++++++++++++++++++ 4 files changed, 1050 insertions(+), 1 deletion(-) create mode 100644 mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index 77986e2..2b622aa 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -215,7 +215,7 @@ class KStubbing(private val mock: T) { return try { Mockito.`when`(mock.methodCall()) } catch (e: NullPointerException) { - throw MockitoKotlinException("NullPointerException thrown when stubbing. If you are trying to stub a generic method, try `onGeneric` instead.", e) + throw MockitoKotlinException("NullPointerException thrown when stubbing.\nThis may be due to two reasons:\n\t- The method you're trying to stub threw an NPE: look at the stack trace below;\n\t- You're trying to stub a generic method: try `onGeneric` instead.", e) } } } diff --git a/mockito-kotlin/src/test/kotlin/test/Classes.kt b/mockito-kotlin/src/test/kotlin/test/Classes.kt index 3476585..e376652 100644 --- a/mockito-kotlin/src/test/kotlin/test/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/test/Classes.kt @@ -36,6 +36,8 @@ open class Open { } open fun stringResult() = "Default" + + fun throwsNPE(): Any = throw NullPointerException("Test") } class Closed diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index eb613c7..0cab562 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -957,6 +957,17 @@ class MockitoTest : TestBase() { expect(mock.stringResult()).toBe("b") } + @Test + fun doReturn_throwsNPE() { + expectErrorWithMessage("look at the stack trace below") on { + + /* When */ + mock { + on { throwsNPE() } doReturn "result" + } + } + } + @Test fun doReturn_withGenericIntReturnType_on() { /* Expect */ diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig new file mode 100644 index 0000000..b06d453 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig @@ -0,0 +1,1036 @@ +package test + +import com.nhaarman.expect.* +import com.nhaarman.mockitokotlin2.* +import org.junit.Test +import org.mockito.Mockito +import org.mockito.Mockito.RETURNS_MOCKS +import org.mockito.exceptions.base.MockitoAssertionError +import org.mockito.exceptions.verification.WantedButNotInvoked +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode.BASIC +<<<<<<< HEAD +import org.mockito.stubbing.Answer +======= +>>>>>>> 91437b8... Improve error message on NPE in +import java.io.* + + +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +@Suppress("DEPRECATION") +class MockitoTest : TestBase() { + + @Test + fun anyString() { + mock().apply { + string("") + verify(this).string(any()) + } + } + + @Test + fun anyClosedClass() { + mock().apply { + closed(Closed()) + verify(this).closed(any()) + } + } + + @Test + fun anyIntArray() { + mock().apply { + intArray(intArrayOf()) + verify(this).intArray(any()) + } + } + + @Test + fun anyClassArray() { + mock().apply { + closedArray(arrayOf(Closed())) + verify(this).closedArray(anyArray()) + } + } + + @Test + fun anyNullableClassArray() { + mock().apply { + closedNullableArray(arrayOf(Closed(), null)) + verify(this).closedNullableArray(anyArray()) + } + } + + @Test + fun anyStringVararg() { + mock().apply { + closedVararg(Closed(), Closed()) + verify(this).closedVararg(anyVararg()) + } + } + + @Test + fun anyNull_neverVerifiesAny() { + mock().apply { + nullableString(null) + verify(this, never()).nullableString(any()) + } + } + + @Test + fun anyNull_verifiesAnyOrNull() { + mock().apply { + nullableString(null) + verify(this).nullableString(anyOrNull()) + } + } + + /** 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 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 checkWithNullArgument_throwsError() { + mock().apply { + nullableString(null) + + expectErrorWithMessage("null").on { + verify(this).nullableString(check {}) + } + } + } + + @Test + fun atLeastXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atLeast(2)).string(any()) + } + } + + @Test + fun testAtLeastOnce() { + mock().apply { + string("") + string("") + + verify(this, atLeastOnce()).string(any()) + } + } + + @Test + fun atMostXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atMost(2)).string(any()) + } + } + + @Test + fun testCalls() { + mock().apply { + string("") + string("") + + inOrder(this).verify(this, calls(2)).string(any()) + } + } + + @Test + fun testInOrderWithLambda() { + /* Given */ + val a = mock<() -> Unit>() + val b = mock<() -> Unit>() + + /* When */ + b() + a() + + /* Then */ + inOrder(a, b) { + verify(b).invoke() + verify(a).invoke() + } + } + + @Test + fun testClearInvocations() { + val mock = mock().apply { + string("") + } + + clearInvocations(mock) + + verify(mock, never()).string(any()) + } + + @Test + fun testDescription() { + try { + mock().apply { + verify(this, description("Test")).string(any()) + } + throw AssertionError("Verify should throw Exception.") + } catch (e: MockitoAssertionError) { + expect(e.message).toContain("Test") + } + } + + @Test + fun testDoAnswer() { + val mock = mock() + + doAnswer { "Test" } + .whenever(mock) + .stringResult() + + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun testDoCallRealMethod() { + val mock = mock() + + doReturn("Test").whenever(mock).stringResult() + doCallRealMethod().whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("Default") + } + + @Test + fun testDoNothing() { + val spy = spy(Open()) + val array = intArrayOf(3) + + doNothing().whenever(spy).modifiesContents(array) + spy.modifiesContents(array) + + expect(array[0]).toBe(3) + } + + @Test + fun testDoReturnValue() { + val mock = mock() + + doReturn("test").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + } + + @Test + fun testDoReturnNullValue() { + val mock = mock() + + doReturn(null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnNullValues() { + val mock = mock() + + doReturn(null, null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnValues() { + val mock = mock() + + doReturn("test", "test2").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + expect(mock.stringResult()).toBe("test2") + } + + @Test + fun testDoThrowClass() { + val mock = mock() + + doThrow(IllegalStateException::class).whenever(mock).go() + + try { + mock.go() + throw AssertionError("Call should have thrown.") + } catch (e: IllegalStateException) { + } + } + + @Test + fun testDoThrow() { + val mock = mock() + + doThrow(IllegalStateException("test")).whenever(mock).go() + + expectErrorWithMessage("test").on { + mock.go() + } + } + + @Test + fun testMockStubbing_lambda() { + /* Given */ + val mock = mock() { + on { stringResult() } doReturn "A" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testMockStubbing_normalOverridesLambda() { + /* Given */ + val mock = mock() { + on { stringResult() }.doReturn("A") + } + whenever(mock.stringResult()).thenReturn("B") + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("B") + } + + @Test + fun testMockStubbing_methodCall() { + /* Given */ + val mock = mock() + mock { + on(mock.stringResult()).doReturn("A") + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testMockStubbing_builder() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doReturn mock + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBeTheSameAs(mock) + } + + @Test + fun testMockStubbing_nullable() { + /* Given */ + val mock = mock { + on { nullableStringResult() } doReturn "Test" + } + + /* When */ + val result = mock.nullableStringResult() + + /* Then */ + expect(result).toBe("Test") + } + + @Test + fun testMockStubbing_doThrow() { + /* Given */ + val mock = mock { + on { builderMethod() } doThrow IllegalArgumentException() + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + } + + @Test + fun testMockStubbing_doThrowClass() { + /* Given */ + val mock = mock { + on { builderMethod() } doThrow IllegalArgumentException::class + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + } + + @Test + fun testMockStubbing_doThrowVarargs() { + /* Given */ + val mock = mock { + on { builderMethod() }.doThrow(IllegalArgumentException(), UnsupportedOperationException()) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: UnsupportedOperationException) { + } + } + + @Test + fun testMockStubbing_doThrowClassVarargs() { + /* Given */ + val mock = mock { + on { builderMethod() }.doThrow(IllegalArgumentException::class, UnsupportedOperationException::class) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: UnsupportedOperationException) { + } + } + + @Test + fun testMockStubbing_doAnswer_lambda() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testMockStubbing_doAnswer_instance() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer Answer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + + @Test + fun testMockStubbing_doAnswer_withArgument() { + /* Given */ + val mock = mock { + on { stringResult(any()) } doAnswer { "${it.arguments[0]}-result" } + } + + /* When */ + val result = mock.stringResult("argument") + + /* Then */ + expect(result).toBe("argument-result") + } + + @Test + fun testMockStubbingAfterCreatingMock() { + val mock = mock() + + //create stub after creation of mock + mock.stub { + on { stringResult() } doReturn "result" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOverrideDefaultStub() { + /* Given mock with stub */ + val mock = mock { + on { stringResult() } doReturn "result1" + } + + /* override stub */ + mock.stub { + on { stringResult() } doReturn "result2" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result2") + } + + @Test + fun mock_withCustomName() { + /* Given */ + val mock = mock("myName") + + /* Expect */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withCustomDefaultAnswer() { + /* Given */ + val mock = mock(Mockito.RETURNS_SELF) + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun mock_withCustomDefaultAnswer_parameterName() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_SELF) + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun mock_withSettings_extraInterfaces() { + /* Given */ + val mock = mock( + withSettings().extraInterfaces(ExtraInterface::class.java) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettings_name() { + /* Given */ + val mock = mock( + withSettings().name("myName") + ) + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettings_defaultAnswer() { + /* Given */ + val mock = mock( + withSettings().defaultAnswer(RETURNS_MOCKS) + ) + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mock_withSettings_serializable() { + /* Given */ + val mock = mock( + withSettings().serializable() + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettings_serializableMode() { + /* Given */ + val mock = mock( + withSettings().serializable(BASIC) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettings_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock( + withSettings().verboseLogging() + ) + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch (e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mock_withSettings_invocationListeners() { + /* Given */ + var bool = false + val mock = mock( + withSettings().invocationListeners(InvocationListener { bool = true }) + ) + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mock_withSettings_stubOnly() { + /* Given */ + val mock = mock( + withSettings().stubOnly() + ) + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettings_useConstructor() { + /* Expect */ + expectErrorWithMessage("Unable to create mock instance of type") on { + mock( + withSettings().useConstructor() + ) + } + } + + @Test + fun mock_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock( + extraInterfaces = arrayOf(ExtraInterface::class) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = RETURNS_MOCKS) + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mock_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch (e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mock_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mock_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + + @Test + fun mockStubbing_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock(extraInterfaces = arrayOf(ExtraInterface::class)) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") {} + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = RETURNS_MOCKS) {} + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mockStubbing_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) {} + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch (e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mockStubbing_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) {} + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mockStubbing_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) {} + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + + @Test + fun stubbingTwiceWithArgumentMatchers() { + /* When */ + val mock = mock { + on { stringResult(argThat { this == "A" }) } doReturn "A" + on { stringResult(argThat { this == "B" }) } doReturn "B" + } + + /* Then */ + expect(mock.stringResult("A")).toBe("A") + expect(mock.stringResult("B")).toBe("B") + } + + @Test + fun stubbingTwiceWithCheckArgumentMatchers_throwsException() { + /* Expect */ + expectErrorWithMessage("null").on { + mock { + on { stringResult(check { }) } doReturn "A" + on { stringResult(check { }) } doReturn "B" + } + } + } + + @Test + fun doReturn_withSingleItemList() { + /* Given */ + val mock = mock { + on { stringResult() } doReturn listOf("a", "b") + } + + /* Then */ + expect(mock.stringResult()).toBe("a") + expect(mock.stringResult()).toBe("b") + } + + @Test + fun doReturn_throwsNPE() { + expectErrorWithMessage("look at the stack trace below") on { + + /* When */ + mock { + on { throwsNPE() } doReturn "result" + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_on() { + /* Expect */ + expectErrorWithMessage("onGeneric") on { + + /* When */ + mock> { + on { genericMethod() } doReturn 2 + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_onGeneric() { + /* Given */ + val mock = mock> { + onGeneric { genericMethod() } doReturn 2 + } + + /* Then */ + expect(mock.genericMethod()).toBe(2) + } + + @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)) + } + } +} \ No newline at end of file -- cgit v1.2.3 From e0d2b0d15dbd93da8e2c47b75a5effac88bd8693 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 3 Dec 2017 22:11:45 +0100 Subject: Accept any `Answer<*>` in `OngoingStubbing.doAnswer` --- .../src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 2 +- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index 2b622aa..f81edff 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -230,7 +230,7 @@ infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubb fun OngoingStubbing.doThrow(t: KClass, vararg ts: KClass): OngoingStubbing = thenThrow(t.java, *ts.map { it.java }.toTypedArray()) infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing = thenAnswer(answer) -infix fun OngoingStubbing.doAnswer(answer: Answer): OngoingStubbing = thenAnswer(answer) +infix fun OngoingStubbing.doAnswer(answer: Answer<*>): OngoingStubbing = thenAnswer(answer) fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! fun never(): VerificationMode = Mockito.never()!! diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 0cab562..1e756d1 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -513,6 +513,19 @@ class MockitoTest : TestBase() { expect(result).toBe("result") } + @Test + fun testMockStubbing_doAnswer_returnsSelf() { + /* Given */ + val mock = mock { + on { builderMethod() } doAnswer Mockito.RETURNS_SELF + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } @Test fun testMockStubbing_doAnswer_withArgument() { -- cgit v1.2.3 From 514eb6513b2e8b4a4f58953085793545dc5542ce Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 3 Dec 2017 22:16:52 +0100 Subject: Allow nullable return types for `onGeneric` --- .../src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 4 ++-- mockito-kotlin/src/test/kotlin/test/Classes.kt | 1 + mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index f81edff..06ae92c 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -193,7 +193,7 @@ inline fun mock(s: MockSettings): T = Mockito.mock(T::class.ja class KStubbing(private val mock: T) { fun on(methodCall: R) = Mockito.`when`(methodCall) - fun onGeneric(methodCall: T.() -> R, c: KClass): OngoingStubbing { + fun onGeneric(methodCall: T.() -> R?, c: KClass): OngoingStubbing { val r = try { mock.methodCall() } catch (e: NullPointerException) { @@ -207,7 +207,7 @@ class KStubbing(private val mock: T) { return Mockito.`when`(r) } - inline fun onGeneric(noinline methodCall: T.() -> R): OngoingStubbing { + inline fun onGeneric(noinline methodCall: T.() -> R?): OngoingStubbing { return onGeneric(methodCall, R::class) } diff --git a/mockito-kotlin/src/test/kotlin/test/Classes.kt b/mockito-kotlin/src/test/kotlin/test/Classes.kt index e376652..cfbb7ab 100644 --- a/mockito-kotlin/src/test/kotlin/test/Classes.kt +++ b/mockito-kotlin/src/test/kotlin/test/Classes.kt @@ -77,6 +77,7 @@ abstract class ThrowingConstructor { interface GenericMethods { fun genericMethod(): T + fun nullableReturnType(): T? } class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index 1e756d1..ab904bb 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -1004,6 +1004,15 @@ class MockitoTest : TestBase() { expect(mock.genericMethod()).toBe(2) } + @Test + fun doReturn_withGenericNullableReturnType_onGeneric() { + val m = mock> { + onGeneric { nullableReturnType() } doReturn "Test" + } + + expect(m.nullableReturnType()).toBe("Test") + } + @Test fun isA_withNonNullableString() { mock().apply { -- cgit v1.2.3 From 688f90b4d873dc8062effea1b7113e77f5573bb3 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 3 Dec 2017 22:29:39 +0100 Subject: Add function to stub an existing mock with lambda syntax --- .../main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 15 +++++---------- mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index 06ae92c..43a8e57 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -25,19 +25,12 @@ package com.nhaarman.mockitokotlin2 -import org.mockito.InOrder -import org.mockito.Incubating -import org.mockito.MockSettings -import org.mockito.MockingDetails -import org.mockito.Mockito +import org.mockito.* import org.mockito.invocation.InvocationOnMock import org.mockito.listeners.InvocationListener import org.mockito.mock.SerializableMode -import org.mockito.stubbing.Answer -import org.mockito.stubbing.OngoingStubbing -import org.mockito.stubbing.Stubber -import org.mockito.verification.VerificationMode -import org.mockito.verification.VerificationWithTimeout +import org.mockito.stubbing.* +import org.mockito.verification.* import kotlin.DeprecationLevel.WARNING import kotlin.reflect.KClass @@ -178,6 +171,8 @@ inline fun mock( KStubbing(this).stubbing(this) }!! +inline fun stubbing(mock: T, stubbing: KStubbing.(T) -> Unit) = KStubbing(mock).stubbing(mock) + inline fun T.stub(stubbing: KStubbing.(T) -> Unit) = this.apply { KStubbing(this).stubbing(this) } @Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(defaultAnswer = a)"), level = WARNING) diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt index ab904bb..86c4b44 100644 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt @@ -1052,4 +1052,18 @@ class MockitoTest : TestBase() { verify(this).nullableString(same(null)) } } + + @Test + fun stubbingExistingMock() { + /* Given */ + val mock = mock() + + /* When */ + stubbing(mock) { + on { stringResult() } doReturn "result" + } + + /* Then */ + expect(mock.stringResult()).toBe("result") + } } \ No newline at end of file -- cgit v1.2.3 From 23de85c9e0f46fb22c57d6e377dc21a9910bcd3d Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Sun, 2 Jul 2017 13:17:42 +0200 Subject: Add dsl stubbing to spied classes. Now it is possible to describe spied classes mock behaviour in dsl form as it was already possible with common mocks. Signed-off-by: Yahor Berdnikau --- .../kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 4 ++++ mockito-kotlin/src/test/kotlin/test/SpyTest.kt | 24 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index 2b622aa..eba1d04 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -243,7 +243,11 @@ fun reset(vararg mocks: T) = Mockito.reset(*mocks) fun same(value: T): T = Mockito.same(value) ?: value inline fun spy(): T = Mockito.spy(T::class.java)!! +inline fun spy(stubbing: KStubbing.(T) -> Unit ): T = Mockito.spy(T::class.java) + .apply { KStubbing(this).stubbing(this) }!! fun spy(value: T): T = Mockito.spy(value)!! +inline fun spy(value: T, stubbing: KStubbing.(T) -> Unit): T = spy(value) + .apply { KStubbing(this).stubbing(this) }!! fun timeout(millis: Long): VerificationWithTimeout = Mockito.timeout(millis)!! fun times(numInvocations: Int): VerificationMode = Mockito.times(numInvocations)!! diff --git a/mockito-kotlin/src/test/kotlin/test/SpyTest.kt b/mockito-kotlin/src/test/kotlin/test/SpyTest.kt index 877d6e3..a8cf14a 100644 --- a/mockito-kotlin/src/test/kotlin/test/SpyTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/SpyTest.kt @@ -71,7 +71,7 @@ class SpyTest : TestBase() { fun doNothingWithSpy() { val date = spy(Date(0)) doNothing().whenever(date).time = 5L - date.time = 5L; + date.time = 5L expect(date.time).toBe(0L) } @@ -90,6 +90,28 @@ class SpyTest : TestBase() { expect(date.time).toBe(0L) } + @Test + fun doReturnWithDefaultInstanceSpyStubbing() { + val timeVal = 12L + + val dateSpy = spy { + on { time } doReturn timeVal + } + + expect(dateSpy.time).toBe(timeVal) + } + + @Test + fun doReturnWithSpyStubbing() { + val timeVal = 15L + + val dateSpy = spy(Date(0)) { + on { time } doReturn timeVal + } + + expect(dateSpy.time).toBe(timeVal) + } + private interface MyInterface private open class MyClass : MyInterface private class ClosedClass -- cgit v1.2.3 From 8a95098b631c772dff9567c9767f14b2e45879da Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 17 Dec 2017 20:43:44 +0100 Subject: Update Expeckt.kt to 1.0.0 --- .gitignore | 1 + mockito-kotlin/build.gradle | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 647ddbc..7ebe4d9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ out/ *.iml .idea/ +!/.idea/codeStyleSettings.xml \ No newline at end of file diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index e32d9b1..56f833f 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -29,7 +29,7 @@ dependencies { /* Tests */ testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:0.6.2" + testCompile "com.nhaarman:expect.kt:1.0.0" } dokka { -- cgit v1.2.3 From da2947211d3f6302cb82ca704bc8e89095489eb4 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 17 Dec 2017 20:45:34 +0100 Subject: Update Mockito to 2.13.0 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 56f833f..0464934 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -25,7 +25,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compile "org.mockito:mockito-core:2.12.0" + compile "org.mockito:mockito-core:2.13.0" /* Tests */ testCompile "junit:junit:4.12" -- cgit v1.2.3 From 9008da351d7c49d2603940ce8b5d84cd5aaff50c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 17 Dec 2017 20:46:34 +0100 Subject: Test using Kotlin 1.2.10 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 09a5879..89bb8fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,13 +9,13 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.0 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.10 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.2.0 + env: TERM=dumb KOTLIN_VERSION=1.2.10 env: -- cgit v1.2.3 From 94768b1ba1e69d9bda47a68daef303a519358312 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 21 Jan 2018 16:45:03 +0100 Subject: Restructure methods into files --- .gitignore | 14 +- .idea/codeStyles/Project.xml | 276 +++++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/copyright/MIT.xml | 6 + .idea/copyright/profiles_settings.xml | 7 + gradle.properties | 27 +- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 34 +- .../com/nhaarman/mockitokotlin2/BDDMockito.kt | 71 +- .../com/nhaarman/mockitokotlin2/CreateInstance.kt | 37 - .../com/nhaarman/mockitokotlin2/KStubbing.kt | 77 ++ .../kotlin/com/nhaarman/mockitokotlin2/Matchers.kt | 128 +++ .../kotlin/com/nhaarman/mockitokotlin2/Mocking.kt | 189 ++++ .../kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 273 +---- .../mockitokotlin2/MockitoKotlinException.kt | 2 +- .../com/nhaarman/mockitokotlin2/OngoingStubbing.kt | 124 +++ .../kotlin/com/nhaarman/mockitokotlin2/Spying.kt | 62 ++ .../kotlin/com/nhaarman/mockitokotlin2/Stubber.kt | 39 +- .../com/nhaarman/mockitokotlin2/Verification.kt | 218 ++++ .../com/nhaarman/mockitokotlin2/VerifyScope.kt | 43 +- .../mockitokotlin2/internal/CreateInstance.kt | 46 + .../nhaarman/mockitokotlin2/internal/MockMaker.kt | 27 +- .../mockitokotlin2/internal/NonNullProvider.kt | 14 - .../nhaarman/mockitokotlin2/internal/NullCaster.kt | 19 - .../src/test/kotlin/test/MatchersTest.kt | 183 ++++ mockito-kotlin/src/test/kotlin/test/MockTest.kt | 92 -- mockito-kotlin/src/test/kotlin/test/MockingTest.kt | 325 ++++++ mockito-kotlin/src/test/kotlin/test/MockitoTest.kt | 1069 -------------------- .../src/test/kotlin/test/MockitoTest.kt.orig | 1036 ------------------- .../src/test/kotlin/test/OngoingStubbingTest.kt | 320 ++++++ mockito-kotlin/src/test/kotlin/test/StubberTest.kt | 103 ++ .../src/test/kotlin/test/VerificationTest.kt | 89 ++ .../kotlin/test/createinstance/NullCasterTest.kt | 8 +- 32 files changed, 2382 insertions(+), 2581 deletions(-) create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/copyright/MIT.xml create mode 100644 .idea/copyright/profiles_settings.xml delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt create mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/MatchersTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/MockTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/MockingTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/MockitoTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig create mode 100644 mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/StubberTest.kt create mode 100644 mockito-kotlin/src/test/kotlin/test/VerificationTest.kt diff --git a/.gitignore b/.gitignore index 7ebe4d9..1f606eb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,15 @@ out/ !gradle-wrapper.jar *.iml -.idea/ -!/.idea/codeStyleSettings.xml \ No newline at end of file +.idea/caches/* +.idea/compiler.xml +.idea/gradle.xml +.idea/kotlinc.xml +.idea/libraries/* +.idea/misc.xml +.idea/modules.xml +.idea/runConfigurations.xml +.idea/shelf +.idea/uiDesigner.xml +.idea/vcs.xml +.idea/workspace.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..69f8a38 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,276 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/MIT.xml b/.idea/copyright/MIT.xml new file mode 100644 index 0000000..63c2a5b --- /dev/null +++ b/.idea/copyright/MIT.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..57aa1f3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 278ac4e..5d8bda0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,26 +1 @@ -# -# The MIT License -# -# Copyright (c) 2016 Niek Haarman -# Copyright (c) 2007 Mockito contributors -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -isRelease = false +isRelease=false diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt index eaefb71..bc26bf5 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2018 Niek Haarman * Copyright (c) 2007 Mockito contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -25,15 +25,35 @@ package com.nhaarman.mockitokotlin2 +import com.nhaarman.mockitokotlin2.internal.createInstance import org.mockito.ArgumentCaptor import kotlin.reflect.KClass -inline fun argumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) -inline fun nullableArgumentCaptor(): KArgumentCaptor = KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) +/** + * Creates a [KArgumentCaptor] for given type. + */ +inline fun argumentCaptor(): KArgumentCaptor { + return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) +} -inline fun capture(captor: ArgumentCaptor): T = captor.capture() ?: createInstance() +/** + * Creates a [KArgumentCaptor] for given nullable type. + */ +inline fun nullableArgumentCaptor(): KArgumentCaptor { + return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) +} + +/** + * Alias for [ArgumentCaptor.capture]. + */ +inline fun capture(captor: ArgumentCaptor): T { + return captor.capture() ?: createInstance() +} -class KArgumentCaptor(private val captor: ArgumentCaptor, private val tClass: KClass<*>) { +class KArgumentCaptor( + private val captor: ArgumentCaptor, + private val tClass: KClass<*> +) { /** * The first captured value of the argument. @@ -67,7 +87,9 @@ class KArgumentCaptor(private val captor: ArgumentCaptor, priva get() = captor.allValues @Suppress("UNCHECKED_CAST") - fun capture(): T = captor.capture() ?: createInstance(tClass) as T + fun capture(): T { + return captor.capture() ?: createInstance(tClass) as T + } } val ArgumentCaptor.firstValue: T diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt index e2771f9..e2ca7ae 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt @@ -1,13 +1,72 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + package com.nhaarman.mockitokotlin2 import org.mockito.BDDMockito +import org.mockito.BDDMockito.BDDMyOngoingStubbing + +/** + * Alias for [BDDMockito.given]. + */ +fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing { + return BDDMockito.given(methodCall) +} + +/** + * Alias for [BDDMockito.given] with a lambda. + */ +fun given(methodCall: () -> T): BDDMyOngoingStubbing { + return given(methodCall()) +} + +/** + * Alias for [BDDMockito.then]. + */ +fun then(mock: T): BDDMockito.Then { + return BDDMockito.then(mock) +} -fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing = BDDMockito.given(methodCall) -fun given(methodCall: () -> T) = given(methodCall()) +/** + * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a lambda. + */ +infix fun BDDMyOngoingStubbing.willAnswer(value: () -> T): BDDMockito.BDDMyOngoingStubbing { + return willAnswer { value() } +} -fun then(mock: T): BDDMockito.Then = BDDMockito.then(mock) +/** + * Alias for [BBDMyOngoingStubbing.willReturn]. + */ +infix fun BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing { + return willReturn(value()) +} -infix fun BDDMockito.BDDMyOngoingStubbing.willAnswer(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willAnswer { value() } -infix fun BDDMockito.BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing = willReturn(value()) -infix fun BDDMockito.BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing = willThrow(value()) +/** + * Alias for [BBDMyOngoingStubbing.willThrow]. + */ +infix fun BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing { + return willThrow(value()) +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt deleted file mode 100644 index 8cb0c32..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/CreateInstance.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import com.nhaarman.mockitokotlin2.internal.NonNullProvider -import kotlin.reflect.KClass -import java.lang.reflect.Array as JavaArray - - -inline fun createInstance(): T - = createInstance(T::class) - -fun createInstance(kClass: KClass): T - = NonNullProvider.create().createInstance(kClass) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt new file mode 100644 index 0000000..4ed5bf5 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import com.nhaarman.mockitokotlin2.internal.createInstance +import org.mockito.Mockito +import org.mockito.stubbing.OngoingStubbing +import kotlin.reflect.KClass + + +inline fun stubbing( + mock: T, + stubbing: KStubbing.(T) -> Unit +) { + KStubbing(mock).stubbing(mock) +} + +inline fun T.stub(stubbing: KStubbing.(T) -> Unit): T { + return apply { KStubbing(this).stubbing(this) } +} + +class KStubbing(private val mock: T) { + + fun on(methodCall: R): OngoingStubbing = Mockito.`when`(methodCall) + + fun onGeneric(methodCall: T.() -> R?, c: KClass): OngoingStubbing { + val r = try { + mock.methodCall() + } catch (e: NullPointerException) { + // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a + // null value for a non-nullable generic type. + // We catch this NPE to return a valid instance. + // The Mockito state has already been modified at this point to reflect + // the wanted changes. + createInstance(c) + } + return Mockito.`when`(r) + } + + inline fun onGeneric(noinline methodCall: T.() -> R?): OngoingStubbing { + return onGeneric(methodCall, R::class) + } + + fun on(methodCall: T.() -> R): OngoingStubbing { + return try { + Mockito.`when`(mock.methodCall()) + } catch (e: NullPointerException) { + throw MockitoKotlinException( + "NullPointerException thrown when stubbing.\nThis may be due to two reasons:\n\t- The method you're trying to stub threw an NPE: look at the stack trace below;\n\t- You're trying to stub a generic method: try `onGeneric` instead.", + e + ) + } + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt new file mode 100644 index 0000000..31cf24d --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt @@ -0,0 +1,128 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import com.nhaarman.mockitokotlin2.internal.createInstance +import org.mockito.Mockito + +/** Object argument that is equal to the given value. */ +fun eq(value: T): T { + return Mockito.eq(value) ?: value +} + +/** Object argument that is the same as the given value. */ +fun same(value: T): T { + return Mockito.same(value) ?: value +} + +/** Matches any object, excluding nulls. */ +inline fun any(): T { + return Mockito.any(T::class.java) ?: createInstance() +} + +/** Matches anything, including nulls. */ +inline fun anyOrNull(): T { + return Mockito.any() ?: createInstance() +} + +/** Matches any vararg object, including nulls. */ +inline fun anyVararg(): T { + return Mockito.any() ?: createInstance() +} + +/** Matches any array of type T. */ +inline fun anyArray(): Array { + return Mockito.any(Array::class.java) ?: arrayOf() +} + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ +inline fun argThat(noinline predicate: T.() -> Boolean): T { + return Mockito.argThat { arg: T? -> arg?.predicate() ?: false } ?: createInstance( + T::class + ) +} + +/** + * Alias for [argThat]. + * + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ +inline fun argForWhich(noinline predicate: T.() -> Boolean): T { + return argThat(predicate) +} + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate A function that returns `true` when given [T] matches the predicate. + */ +inline fun argWhere(noinline predicate: (T) -> Boolean): T { + return argThat(predicate) +} + +/** + * Argument that implements the given class. + */ +inline fun isA(): T { + return Mockito.isA(T::class.java) ?: createInstance() +} + +/** + * `null` argument. + */ +fun isNull(): T? = Mockito.isNull() + +/** + * Not `null` argument. + */ +fun isNotNull(): T? { + return Mockito.isNotNull() +} + +/** + * Not `null` argument. + */ +fun notNull(): T? { + return Mockito.notNull() +} + +/** + * Object argument that is reflection-equal to the given value with support for excluding + * selected fields from a class. + */ +fun refEq(value: T, vararg excludeFields: String): T? { + return Mockito.refEq(value, *excludeFields) +} + diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt new file mode 100644 index 0000000..8300ec9 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt @@ -0,0 +1,189 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import org.mockito.Incubating +import org.mockito.MockSettings +import org.mockito.Mockito +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode +import org.mockito.stubbing.Answer +import kotlin.DeprecationLevel.ERROR +import kotlin.reflect.KClass + +/** + * Creates a mock for [T]. + * + * @param extraInterfaces Specifies extra interfaces the mock should implement. + * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. + * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. + * @param defaultAnswer Specifies default answers to interactions. + * @param serializable Configures the mock to be serializable. + * @param serializableMode Configures the mock to be serializable with a specific serializable mode. + * @param verboseLogging Enables real-time logging of method invocations on this mock. + * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. + * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. + * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. + * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + */ +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null +): T { + return Mockito.mock( + T::class.java, + withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance + ) + )!! +} + +/** + * Creates a mock for [T], allowing for immediate stubbing. + * + * @param extraInterfaces Specifies extra interfaces the mock should implement. + * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. + * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. + * @param defaultAnswer Specifies default answers to interactions. + * @param serializable Configures the mock to be serializable. + * @param serializableMode Configures the mock to be serializable with a specific serializable mode. + * @param verboseLogging Enables real-time logging of method invocations on this mock. + * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. + * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. + * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. + * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + */ +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null, + stubbing: KStubbing.(T) -> Unit +): T { + return Mockito.mock( + T::class.java, + withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance + ) + ).apply { KStubbing(this).stubbing(this) }!! +} + +/** + * Allows mock creation with additional mock settings. + * See [MockSettings]. + * + * @param extraInterfaces Specifies extra interfaces the mock should implement. + * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. + * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. + * @param defaultAnswer Specifies default answers to interactions. + * @param serializable Configures the mock to be serializable. + * @param serializableMode Configures the mock to be serializable with a specific serializable mode. + * @param verboseLogging Enables real-time logging of method invocations on this mock. + * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. + * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. + * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. + * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + */ +fun withSettings( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: Boolean = false, + @Incubating outerInstance: Any? = null +): MockSettings = Mockito.withSettings().apply { + extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } + name?.let { name(it) } + spiedInstance?.let { spiedInstance(it) } + defaultAnswer?.let { defaultAnswer(it) } + if (serializable) serializable() + serializableMode?.let { serializable(it) } + if (verboseLogging) verboseLogging() + invocationListeners?.let { invocationListeners(*it) } + if (stubOnly) stubOnly() + if (useConstructor) useConstructor() + outerInstance?.let { outerInstance(it) } +} + + +@Deprecated( + "Use mock() with optional arguments instead.", + ReplaceWith("mock(defaultAnswer = a)"), + level = ERROR +) +inline fun mock(a: Answer): T = mock(defaultAnswer = a) + +@Deprecated( + "Use mock() with optional arguments instead.", + ReplaceWith("mock(name = s)"), + level = ERROR +) +inline fun mock(s: String): T = mock(name = s) + +@Suppress("DeprecatedCallableAddReplaceWith") +@Deprecated("Use mock() with optional arguments instead.", level = ERROR) +inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt index 77d6454..3f52873 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2018 Niek Haarman * Copyright (c) 2007 Mockito contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -25,272 +25,17 @@ package com.nhaarman.mockitokotlin2 -import org.mockito.* -import org.mockito.invocation.InvocationOnMock -import org.mockito.listeners.InvocationListener -import org.mockito.mock.SerializableMode -import org.mockito.stubbing.* -import org.mockito.verification.* -import kotlin.DeprecationLevel.WARNING -import kotlin.reflect.KClass +import org.mockito.MockingDetails +import org.mockito.Mockito -fun after(millis: Long) = Mockito.after(millis) - -/** Matches any object, excluding nulls. */ -inline fun any() = Mockito.any(T::class.java) ?: createInstance() - -/** Matches anything, including nulls. */ -inline fun anyOrNull(): T = Mockito.any() ?: createInstance() - -/** Matches any vararg object, including nulls. */ -inline fun anyVararg(): T = Mockito.any() ?: createInstance() - -/** Matches any array of type T. */ -inline fun anyArray(): Array = Mockito.any(Array::class.java) ?: arrayOf() - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. - */ -inline fun argThat(noinline predicate: T.() -> Boolean) = Mockito.argThat { arg -> arg?.predicate() ?: false } ?: createInstance(T::class) - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. - */ -inline fun argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate) - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate A function that returns `true` when given [T] matches the predicate. - */ -inline fun argWhere(noinline predicate: (T) -> Boolean) = argThat(predicate) - -/** - * For usage with verification only. - * - * For example: - * verify(myObject).doSomething(check { assertThat(it, is("Test")) }) - * - * @param predicate A function that performs actions to verify an argument [T]. - */ -inline fun check(noinline predicate: (T) -> Unit) = Mockito.argThat { arg -> - if (arg == null) error("""The argument passed to the predicate was null. - -If you are trying to verify an argument to be null, use `isNull()`. -If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. -""".trimIndent()) - predicate(arg) - true -} ?: createInstance(T::class) - -fun atLeast(numInvocations: Int): VerificationMode = Mockito.atLeast(numInvocations)!! -fun atLeastOnce(): VerificationMode = Mockito.atLeastOnce()!! -fun atMost(maxNumberOfInvocations: Int): VerificationMode = Mockito.atMost(maxNumberOfInvocations)!! -fun calls(wantedNumberOfInvocations: Int): VerificationMode = Mockito.calls(wantedNumberOfInvocations)!! - -fun clearInvocations(vararg mocks: T) = Mockito.clearInvocations(*mocks) -fun description(description: String): VerificationMode = Mockito.description(description) - -fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber = Mockito.doAnswer { answer(it) }!! - -fun doCallRealMethod(): Stubber = Mockito.doCallRealMethod()!! -fun doNothing(): Stubber = Mockito.doNothing()!! -fun doReturn(value: Any?): Stubber = Mockito.doReturn(value)!! -fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber = Mockito.doReturn(toBeReturned, *toBeReturnedNext)!! -fun doThrow(toBeThrown: KClass): Stubber = Mockito.doThrow(toBeThrown.java)!! -fun doThrow(vararg toBeThrown: Throwable): Stubber = Mockito.doThrow(*toBeThrown)!! - -fun eq(value: T): T = Mockito.eq(value) ?: value -fun ignoreStubs(vararg mocks: Any): Array = Mockito.ignoreStubs(*mocks)!! -fun inOrder(vararg mocks: Any): InOrder = Mockito.inOrder(*mocks)!! -fun inOrder(vararg mocks: Any, evaluation: InOrder.() -> Unit) = Mockito.inOrder(*mocks).evaluation() - -inline fun isA(): T = Mockito.isA(T::class.java) ?: createInstance() -fun isNotNull(): T? = Mockito.isNotNull() -fun isNull(): T? = Mockito.isNull() - -inline fun mock( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, - @Incubating outerInstance: Any? = null -): T = Mockito.mock(T::class.java, withSettings( - extraInterfaces = extraInterfaces, - name = name, - spiedInstance = spiedInstance, - defaultAnswer = defaultAnswer, - serializable = serializable, - serializableMode = serializableMode, - verboseLogging = verboseLogging, - invocationListeners = invocationListeners, - stubOnly = stubOnly, - useConstructor = useConstructor, - outerInstance = outerInstance -))!! - -inline fun mock( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, - @Incubating outerInstance: Any? = null, - stubbing: KStubbing.(T) -> Unit -): T = Mockito.mock(T::class.java, withSettings( - extraInterfaces = extraInterfaces, - name = name, - spiedInstance = spiedInstance, - defaultAnswer = defaultAnswer, - serializable = serializable, - serializableMode = serializableMode, - verboseLogging = verboseLogging, - invocationListeners = invocationListeners, - stubOnly = stubOnly, - useConstructor = useConstructor, - outerInstance = outerInstance -)).apply { - KStubbing(this).stubbing(this) -}!! - -inline fun stubbing(mock: T, stubbing: KStubbing.(T) -> Unit) = KStubbing(mock).stubbing(mock) - -inline fun T.stub(stubbing: KStubbing.(T) -> Unit) = this.apply { KStubbing(this).stubbing(this) } - -@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(defaultAnswer = a)"), level = WARNING) -inline fun mock(a: Answer): T = mock(defaultAnswer = a) - -@Deprecated("Use mock() with optional arguments instead.", ReplaceWith("mock(name = s)"), level = WARNING) -inline fun mock(s: String): T = mock(name = s) - -@Suppress("DeprecatedCallableAddReplaceWith") -@Deprecated("Use mock() with optional arguments instead.", level = WARNING) -inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! - -class KStubbing(private val mock: T) { - fun on(methodCall: R) = Mockito.`when`(methodCall) - - fun onGeneric(methodCall: T.() -> R?, c: KClass): OngoingStubbing { - val r = try { - mock.methodCall() - } catch (e: NullPointerException) { - // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a - // null value for a non-nullable generic type. - // We catch this NPE to return a valid instance. - // The Mockito state has already been modified at this point to reflect - // the wanted changes. - createInstance(c) - } - return Mockito.`when`(r) - } - - inline fun onGeneric(noinline methodCall: T.() -> R?): OngoingStubbing { - return onGeneric(methodCall, R::class) - } - - fun on(methodCall: T.() -> R): OngoingStubbing { - return try { - Mockito.`when`(mock.methodCall()) - } catch (e: NullPointerException) { - throw MockitoKotlinException("NullPointerException thrown when stubbing.\nThis may be due to two reasons:\n\t- The method you're trying to stub threw an NPE: look at the stack trace below;\n\t- You're trying to stub a generic method: try `onGeneric` instead.", e) - } - } +fun validateMockitoUsage() { + Mockito.validateMockitoUsage() } -infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing = thenReturn(t) -fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing = thenReturn(t, *ts) -inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing = thenReturn(ts[0], *ts.drop(1).toTypedArray()) - -infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing = thenThrow(t) -fun OngoingStubbing.doThrow(t: Throwable, vararg ts: Throwable): OngoingStubbing = thenThrow(t, *ts) -infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing = thenThrow(t.java) -fun OngoingStubbing.doThrow(t: KClass, vararg ts: KClass): OngoingStubbing = thenThrow(t.java, *ts.map { it.java }.toTypedArray()) - -infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing = thenAnswer(answer) -infix fun OngoingStubbing.doAnswer(answer: Answer<*>): OngoingStubbing = thenAnswer(answer) - -fun mockingDetails(toInspect: Any): MockingDetails = Mockito.mockingDetails(toInspect)!! -fun never(): VerificationMode = Mockito.never()!! -fun notNull(): T? = Mockito.notNull() -fun only(): VerificationMode = Mockito.only()!! -fun refEq(value: T, vararg excludeFields: String): T? = Mockito.refEq(value, *excludeFields) - -fun reset(vararg mocks: T) = Mockito.reset(*mocks) - -fun same(value: T): T = Mockito.same(value) ?: value - -inline fun spy(): T = Mockito.spy(T::class.java)!! -inline fun spy(stubbing: KStubbing.(T) -> Unit ): T = Mockito.spy(T::class.java) - .apply { KStubbing(this).stubbing(this) }!! -fun spy(value: T): T = Mockito.spy(value)!! -inline fun spy(value: T, stubbing: KStubbing.(T) -> Unit): T = spy(value) - .apply { KStubbing(this).stubbing(this) }!! - -fun timeout(millis: Long): VerificationWithTimeout = Mockito.timeout(millis)!! -fun times(numInvocations: Int): VerificationMode = Mockito.times(numInvocations)!! -fun validateMockitoUsage() = Mockito.validateMockitoUsage() - -fun verify(mock: T): T = Mockito.verify(mock)!! -fun verify(mock: T, mode: VerificationMode): T = Mockito.verify(mock, mode)!! -fun verifyNoMoreInteractions(vararg mocks: T) = Mockito.verifyNoMoreInteractions(*mocks) -fun verifyZeroInteractions(vararg mocks: Any) = Mockito.verifyZeroInteractions(*mocks) - -fun whenever(methodCall: T): OngoingStubbing = Mockito.`when`(methodCall)!! - -fun withSettings( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, - @Incubating outerInstance: Any? = null -): MockSettings = Mockito.withSettings().apply { - extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } - name?.let { name(it) } - spiedInstance?.let { spiedInstance(it) } - defaultAnswer?.let { defaultAnswer(it) } - if (serializable) serializable() - serializableMode?.let { serializable(it) } - if (verboseLogging) verboseLogging() - invocationListeners?.let { invocationListeners(*it) } - if (stubOnly) stubOnly() - if (useConstructor) useConstructor() - outerInstance?.let { outerInstance(it) } +fun reset(vararg mocks: T) { + Mockito.reset(*mocks) } -/** - * Verify multiple calls on mock - * Supports an easier to read style of - * - * ``` - * verify(mock) { - * 2 * { call() } - * } - * ``` - */ -inline fun verify(mock: T, block: VerifyScope.() -> Unit) { - VerifyScope(mock).block() +fun mockingDetails(toInspect: Any): MockingDetails { + return Mockito.mockingDetails(toInspect)!! } \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt index ed18007..d079b8f 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2018 Niek Haarman * Copyright (c) 2007 Mockito contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt new file mode 100644 index 0000000..9f28d6b --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt @@ -0,0 +1,124 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import org.mockito.Mockito +import org.mockito.invocation.InvocationOnMock +import org.mockito.stubbing.Answer +import org.mockito.stubbing.OngoingStubbing +import kotlin.reflect.KClass + + +/** + * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called. + * + * Alias for [Mockito.when]. + */ +fun whenever(methodCall: T): OngoingStubbing { + return Mockito.`when`(methodCall)!! +} + +/** + * Sets a return value to be returned when the method is called. + * + * Alias for [OngoingStubbing.thenReturn]. + */ +infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing { + return thenReturn(t) +} + +/** + * Sets consecutive return values to be returned when the method is called. + * + * Alias for [OngoingStubbing.thenReturn]. + */ +fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing { + return thenReturn(t, *ts) +} + +/** + * Sets consecutive return values to be returned when the method is called. + */ +inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing { + return thenReturn( + ts[0], + *ts.drop(1).toTypedArray() + ) +} + +/** + * Sets Throwable objects to be thrown when the method is called. + * + * Alias for [OngoingStubbing.thenThrow]. + */ +infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing { + return thenThrow(t) +} + +/** + * Sets Throwable objects to be thrown when the method is called. + * + * Alias for [OngoingStubbing.doThrow]. + */ +fun OngoingStubbing.doThrow( + t: Throwable, + vararg ts: Throwable +): OngoingStubbing { + return thenThrow(t, *ts) +} + +/** + * Sets a Throwable type to be thrown when the method is called. + */ +infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing { + return thenThrow(t.java) +} + +/** + * Sets Throwable classes to be thrown when the method is called. + */ +fun OngoingStubbing.doThrow( + t: KClass, + vararg ts: KClass +): OngoingStubbing { + return thenThrow(t.java, *ts.map { it.java }.toTypedArray()) +} + +/** + * Sets a generic Answer for the method. + * + * Alias for [OngoingStubbing.thenAnswer]. + */ +infix fun OngoingStubbing.doAnswer(answer: Answer<*>): OngoingStubbing { + return thenAnswer(answer) +} + +/** + * Sets a generic Answer for the method using a lambda. + */ +infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing { + return thenAnswer(answer) +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt new file mode 100644 index 0000000..340c562 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt @@ -0,0 +1,62 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import org.mockito.Mockito + + +/** + * Creates a spy of the real object. + * The spy calls real methods unless they are stubbed. + */ +inline fun spy(): T { + return Mockito.spy(T::class.java)!! +} + +/** + * Creates a spy of the real object, allowing for immediate stubbing. + * The spy calls real methods unless they are stubbed. + */ +inline fun spy(stubbing: KStubbing.(T) -> Unit): T { + return Mockito.spy(T::class.java) + .apply { KStubbing(this).stubbing(this) }!! +} + +/** + * Creates a spy of the real object. The spy calls real methods unless they are stubbed. + */ +fun spy(value: T): T { + return Mockito.spy(value)!! +} + +/** + * Creates a spy of the real object, allowing for immediate stubbing. + * The spy calls real methods unless they are stubbed. + */ +inline fun spy(value: T, stubbing: KStubbing.(T) -> Unit): T { + return spy(value) + .apply { KStubbing(this).stubbing(this) }!! +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt index 45b0d07..a6aee54 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2018 Niek Haarman * Copyright (c) 2007 Mockito contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -25,6 +25,41 @@ package com.nhaarman.mockitokotlin2 +import org.mockito.Mockito +import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Stubber +import kotlin.reflect.KClass -fun Stubber.whenever(mock: T) = `when`(mock) + +fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber { + return Mockito.doAnswer { answer(it) }!! +} + +fun doCallRealMethod(): Stubber { + return Mockito.doCallRealMethod()!! +} + +fun doNothing(): Stubber { + return Mockito.doNothing()!! +} + +fun doReturn(value: Any?): Stubber { + return Mockito.doReturn(value)!! +} + +fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber { + return Mockito.doReturn( + toBeReturned, + *toBeReturnedNext + )!! +} + +fun doThrow(toBeThrown: KClass): Stubber { + return Mockito.doThrow(toBeThrown.java)!! +} + +fun doThrow(vararg toBeThrown: Throwable): Stubber { + return Mockito.doThrow(*toBeThrown)!! +} + +fun Stubber.whenever(mock: T) = `when`(mock) \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt new file mode 100644 index 0000000..1db20a6 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -0,0 +1,218 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2 + +import com.nhaarman.mockitokotlin2.internal.createInstance +import org.mockito.InOrder +import org.mockito.Mockito +import org.mockito.verification.VerificationAfterDelay +import org.mockito.verification.VerificationMode +import org.mockito.verification.VerificationWithTimeout + +/** + * Verifies certain behavior happened once. + * + * Alias for [Mockito.verify]. + */ +fun verify(mock: T): T { + return Mockito.verify(mock)!! +} + +/** + * Verifies certain behavior happened at least once / exact number of times / never. + * + * Alias for [Mockito.verify]. + */ +fun verify(mock: T, mode: VerificationMode): T { + return Mockito.verify(mock, mode)!! +} + +/** + * Checks if any of given mocks has any unverified interaction. + * + * Alias for [Mockito.verifyNoMoreInteractions]. + */ +fun verifyNoMoreInteractions(vararg mocks: T) { + Mockito.verifyNoMoreInteractions(*mocks) +} + +/** + * Verifies that no interactions happened on given mocks beyond the previously verified interactions. + * + * Alias for [Mockito.verifyZeroInteractions]. + */ +fun verifyZeroInteractions(vararg mocks: Any) { + Mockito.verifyZeroInteractions(*mocks) +} + +/** + * Allows verifying exact number of invocations. + * + * Alias for [Mockito.times]. + */ +fun times(numInvocations: Int): VerificationMode { + return Mockito.times(numInvocations)!! +} + +/** + * Allows at-least-x verification. + * + * Alias for [Mockito.atLeast]. + */ +fun atLeast(numInvocations: Int): VerificationMode { + return Mockito.atLeast(numInvocations)!! +} + +/** + * Allows at-least-once verification. + * + * Alias for [Mockito.atLeastOnce]. + */ +fun atLeastOnce(): VerificationMode { + return Mockito.atLeastOnce()!! +} + +/** + * Allows at-most-x verification. + * + * Alias for [Mockito.atMost]. + */ +fun atMost(maxNumberOfInvocations: Int): VerificationMode { + return Mockito.atMost(maxNumberOfInvocations)!! +} + +/** + * Allows non-greedy verification in order. + * + * Alias for [Mockito.calls]. + */ +fun calls(wantedNumberOfInvocations: Int): VerificationMode { + return Mockito.calls(wantedNumberOfInvocations)!! +} + +/** + * Alias for [times] with parameter `0`. + */ +fun never(): VerificationMode { + return Mockito.never()!! +} + +/** + * Use this method in order to only clear invocations, when stubbing is non-trivial. + * + * Alias for [Mockito.clearInvocations]. + */ +fun clearInvocations(vararg mocks: T) { + Mockito.clearInvocations(*mocks) +} + +/** + * Adds a description to be printed if verification fails. + * + * Alias for [Mockito.description]. + */ +fun description(description: String): VerificationMode { + return Mockito.description(description) +} + +/** + * Allows verifying over a given period. It causes a verify to wait for a specified period of time for a desired + * interaction rather than failing immediately if has not already happened. May be useful for testing in concurrent + * conditions. + */ +fun after(millis: Long): VerificationAfterDelay? { + return Mockito.after(millis) +} + +/** + * Allows verifying with timeout. It causes a verify to wait for a specified period of time for a desired + * interaction rather than fails immediately if has not already happened. May be useful for testing in concurrent + * conditions. + */ +fun timeout(millis: Long): VerificationWithTimeout { + return Mockito.timeout(millis)!! +} + +/** + * Ignores stubbed methods of given mocks for the sake of verification. + * + * Alias for [Mockito.ignoreStubs]. + */ +fun ignoreStubs(vararg mocks: Any): Array { + return Mockito.ignoreStubs(*mocks)!! +} + +/** + * Creates [InOrder] object that allows verifying mocks in order. + * + * Alias for [Mockito.inOrder]. + */ +fun inOrder(vararg mocks: Any): InOrder { + return Mockito.inOrder(*mocks)!! +} + +/** + * Creates [InOrder] object that allows verifying mocks in order. + * Accepts a lambda to allow easy evaluation. + * + * Alias for [Mockito.inOrder]. + */ +fun inOrder( + vararg mocks: Any, + evaluation: InOrder.() -> Unit +) { + Mockito.inOrder(*mocks).evaluation() +} + +/** + * Allows checking if given method was the only one invoked. + */ +fun only(): VerificationMode { + return Mockito.only()!! +} + + +/** + * For usage with verification only. + * + * For example: + * verify(myObject).doSomething(check { assertThat(it, is("Test")) }) + * + * @param predicate A function that performs actions to verify an argument [T]. + */ +inline fun check(noinline predicate: (T) -> Unit): T { + return Mockito.argThat { arg: T? -> + if (arg == null) error( + """The argument passed to the predicate was null. + +If you are trying to verify an argument to be null, use `isNull()`. +If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. +""".trimIndent() + ) + predicate(arg) + true + } ?: createInstance(T::class) +} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt index 92b2ef0..6ef3c33 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt @@ -1,6 +1,47 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + package com.nhaarman.mockitokotlin2 -class VerifyScope(val mock: T) { + +/** + * Verify multiple calls on mock + * Supports an easier to read style of + * + * ``` + * verify(mock) { + * 2 * { call() } + * } + * ``` + */ +inline fun verify(mock: T, block: VerifyScope.() -> Unit) { + VerifyScope(mock).block() +} + +class VerifyScope(val mock: T) { + operator inline fun Int.times(call: T.() -> Unit) { verify(mock, com.nhaarman.mockitokotlin2.times(this)).call() } diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt new file mode 100644 index 0000000..6041238 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt @@ -0,0 +1,46 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.nhaarman.mockitokotlin2.internal + +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + +inline fun createInstance(): T { + return createInstance(T::class) +} + +fun createInstance(kClass: KClass): T { + return castNull() +} + +/** + * Uses a quirk in the bytecode generated by Kotlin + * to cast [null] to a non-null type. + * + * See https://youtrack.jetbrains.com/issue/KT-8135. + */ +@Suppress("UNCHECKED_CAST") +private fun castNull(): T = null as T diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt index dc3e281..307f3dc 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt @@ -1,3 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + package com.nhaarman.mockitokotlin2.internal import org.mockito.internal.configuration.plugins.Plugins @@ -6,5 +31,5 @@ import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker internal var mockMakerInlineEnabled: Boolean? = null internal fun mockMakerInlineEnabled(): Boolean { return mockMakerInlineEnabled ?: - Plugins.getMockMaker() is InlineByteBuddyMockMaker + Plugins.getMockMaker() is InlineByteBuddyMockMaker } diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt deleted file mode 100644 index 247a207..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NonNullProvider.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.nhaarman.mockitokotlin2.internal - -import kotlin.reflect.KClass -import java.lang.reflect.Array as JavaArray - -internal interface NonNullProvider { - - fun createInstance(kClass: KClass): T - - companion object Factory { - - fun create(): NonNullProvider = NullCaster() - } -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt deleted file mode 100644 index 7bb0479..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/NullCaster.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.nhaarman.mockitokotlin2.internal - -import kotlin.reflect.KClass - -/** - * Uses a quirk in the bytecode generated by Kotlin - * to cast [null] to a non-null type. - * - * See https://youtrack.jetbrains.com/issue/KT-8135. - */ -internal class NullCaster : NonNullProvider { - - override fun createInstance(kClass: KClass): T { - return castNull() - } - - @Suppress("UNCHECKED_CAST") - private fun castNull(): T = null as T -} diff --git a/mockito-kotlin/src/test/kotlin/test/MatchersTest.kt b/mockito-kotlin/src/test/kotlin/test/MatchersTest.kt new file mode 100644 index 0000000..312d7a0 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/MatchersTest.kt @@ -0,0 +1,183 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockitokotlin2.* +import org.junit.Test +import java.io.IOException + +class MatchersTest : TestBase() { + + @Test + fun anyString() { + mock().apply { + string("") + verify(this).string(any()) + } + } + + @Test + fun anyClosedClass() { + mock().apply { + closed(Closed()) + verify(this).closed(any()) + } + } + + @Test + fun anyIntArray() { + mock().apply { + intArray(intArrayOf()) + verify(this).intArray(any()) + } + } + + @Test + fun anyClassArray() { + mock().apply { + closedArray(arrayOf(Closed())) + verify(this).closedArray(anyArray()) + } + } + + @Test + fun anyNullableClassArray() { + mock().apply { + closedNullableArray(arrayOf(Closed(), null)) + verify(this).closedNullableArray(anyArray()) + } + } + + @Test + fun anyStringVararg() { + mock().apply { + closedVararg(Closed(), Closed()) + verify(this).closedVararg(anyVararg()) + } + } + + @Test + fun anyNull_neverVerifiesAny() { + mock().apply { + nullableString(null) + verify(this, never()).nullableString(any()) + } + } + + @Test + fun anyNull_verifiesAnyOrNull() { + mock().apply { + nullableString(null) + verify(this).nullableString(anyOrNull()) + } + } + + /** 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 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 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)) + } + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/MockTest.kt b/mockito-kotlin/src/test/kotlin/test/MockTest.kt deleted file mode 100644 index f17bbda..0000000 --- a/mockito-kotlin/src/test/kotlin/test/MockTest.kt +++ /dev/null @@ -1,92 +0,0 @@ -package test/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.whenever -import org.junit.Test -import org.mockito.Mockito.RETURNS_DEEP_STUBS -import java.util.* - -class MockTest : TestBase() { - - private lateinit var propertyInterfaceVariable: MyInterface - private lateinit var propertyClassVariable: MyClass - - @Test - fun localInterfaceValue() { - /* When */ - val instance: MyInterface = mock() - - /* Then */ - expect(instance).toNotBeNull() - } - - @Test - fun propertyInterfaceVariable() { - /* When */ - propertyInterfaceVariable = mock() - - /* Then */ - expect(propertyInterfaceVariable).toNotBeNull() - } - - @Test - fun localClassValue() { - /* When */ - val instance: MyClass = mock() - - /* Then */ - expect(instance).toNotBeNull() - } - - @Test - fun propertyClassVariable() { - /* When */ - propertyClassVariable = mock() - - /* Then */ - expect(propertyClassVariable).toNotBeNull() - } - - @Test - fun untypedVariable() { - /* When */ - val instance = mock() - - expect(instance).toNotBeNull() - } - - @Test - fun deepStubs() { - val cal: Calendar = mock(defaultAnswer = RETURNS_DEEP_STUBS) - whenever(cal.time.time).thenReturn(123L) - expect(cal.time.time).toBe(123L) - } - - private interface MyInterface - private open class MyClass -} - diff --git a/mockito-kotlin/src/test/kotlin/test/MockingTest.kt b/mockito-kotlin/src/test/kotlin/test/MockingTest.kt new file mode 100644 index 0000000..0d5730b --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/MockingTest.kt @@ -0,0 +1,325 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.expect.fail +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever +import org.junit.Test +import org.mockito.Mockito +import org.mockito.exceptions.verification.WantedButNotInvoked +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode.BASIC +import java.io.PrintStream +import java.io.Serializable +import java.util.* + +class MockingTest : TestBase() { + + private lateinit var propertyInterfaceVariable: MyInterface + private lateinit var propertyClassVariable: MyClass + + @Test + fun localInterfaceValue() { + /* When */ + val instance: MyInterface = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyInterfaceVariable() { + /* When */ + propertyInterfaceVariable = mock() + + /* Then */ + expect(propertyInterfaceVariable).toNotBeNull() + } + + @Test + fun localClassValue() { + /* When */ + val instance: MyClass = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyClassVariable() { + /* When */ + propertyClassVariable = mock() + + /* Then */ + expect(propertyClassVariable).toNotBeNull() + } + + @Test + fun untypedVariable() { + /* When */ + val instance = mock() + + expect(instance).toNotBeNull() + } + + @Test + fun deepStubs() { + val cal: Calendar = mock(defaultAnswer = Mockito.RETURNS_DEEP_STUBS) + whenever(cal.time.time).thenReturn(123L) + expect(cal.time.time).toBe(123L) + } + + + @Test + fun testMockStubbing_lambda() { + /* Given */ + val mock = mock() { + on { stringResult() } doReturn "A" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testMockStubbing_normalOverridesLambda() { + /* Given */ + val mock = mock() { + on { stringResult() }.doReturn("A") + } + whenever(mock.stringResult()).thenReturn("B") + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("B") + } + + + + @Test + fun mock_withCustomDefaultAnswer_parameterName() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_SELF) + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun mock_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock( + extraInterfaces = arrayOf(ExtraInterface::class) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_MOCKS) + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mock_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch (e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mock_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mock_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + + @Test + fun mockStubbing_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock(extraInterfaces = arrayOf(ExtraInterface::class)) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") {} + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_MOCKS) {} + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mockStubbing_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) {} + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch (e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mockStubbing_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) {} + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mockStubbing_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) {} + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + + private interface MyInterface + private open class MyClass +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt deleted file mode 100644 index 86c4b44..0000000 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt +++ /dev/null @@ -1,1069 +0,0 @@ -package test - -import com.nhaarman.expect.* -import com.nhaarman.mockitokotlin2.* -import org.junit.Test -import org.mockito.Mockito -import org.mockito.Mockito.RETURNS_MOCKS -import org.mockito.exceptions.base.MockitoAssertionError -import org.mockito.exceptions.verification.WantedButNotInvoked -import org.mockito.listeners.InvocationListener -import org.mockito.mock.SerializableMode.BASIC -import org.mockito.stubbing.Answer -import java.io.* - - -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -@Suppress("DEPRECATION") -class MockitoTest : TestBase() { - - @Test - fun anyString() { - mock().apply { - string("") - verify(this).string(any()) - } - } - - @Test - fun anyClosedClass() { - mock().apply { - closed(Closed()) - verify(this).closed(any()) - } - } - - @Test - fun anyIntArray() { - mock().apply { - intArray(intArrayOf()) - verify(this).intArray(any()) - } - } - - @Test - fun anyClassArray() { - mock().apply { - closedArray(arrayOf(Closed())) - verify(this).closedArray(anyArray()) - } - } - - @Test - fun anyNullableClassArray() { - mock().apply { - closedNullableArray(arrayOf(Closed(), null)) - verify(this).closedNullableArray(anyArray()) - } - } - - @Test - fun anyStringVararg() { - mock().apply { - closedVararg(Closed(), Closed()) - verify(this).closedVararg(anyVararg()) - } - } - - @Test - fun anyNull_neverVerifiesAny() { - mock().apply { - nullableString(null) - verify(this, never()).nullableString(any()) - } - } - - @Test - fun anyNull_verifiesAnyOrNull() { - mock().apply { - nullableString(null) - verify(this).nullableString(anyOrNull()) - } - } - - /** 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 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 checkWithNullArgument_throwsError() { - mock().apply { - nullableString(null) - - expectErrorWithMessage("null").on { - verify(this).nullableString(check {}) - } - } - } - - @Test - fun atLeastXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atLeast(2)).string(any()) - } - } - - @Test - fun testAtLeastOnce() { - mock().apply { - string("") - string("") - - verify(this, atLeastOnce()).string(any()) - } - } - - @Test - fun atMostXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atMost(2)).string(any()) - } - } - - @Test - fun testCalls() { - mock().apply { - string("") - string("") - - inOrder(this).verify(this, calls(2)).string(any()) - } - } - - @Test - fun testInOrderWithLambda() { - /* Given */ - val a = mock<() -> Unit>() - val b = mock<() -> Unit>() - - /* When */ - b() - a() - - /* Then */ - inOrder(a, b) { - verify(b).invoke() - verify(a).invoke() - } - } - - @Test - fun testClearInvocations() { - val mock = mock().apply { - string("") - } - - clearInvocations(mock) - - verify(mock, never()).string(any()) - } - - @Test - fun testDescription() { - try { - mock().apply { - verify(this, description("Test")).string(any()) - } - throw AssertionError("Verify should throw Exception.") - } catch (e: MockitoAssertionError) { - expect(e.message).toContain("Test") - } - } - - @Test - fun testDoAnswer() { - val mock = mock() - - doAnswer { "Test" } - .whenever(mock) - .stringResult() - - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun testDoCallRealMethod() { - val mock = mock() - - doReturn("Test").whenever(mock).stringResult() - doCallRealMethod().whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("Default") - } - - @Test - fun testDoNothing() { - val spy = spy(Open()) - val array = intArrayOf(3) - - doNothing().whenever(spy).modifiesContents(array) - spy.modifiesContents(array) - - expect(array[0]).toBe(3) - } - - @Test - fun testDoReturnValue() { - val mock = mock() - - doReturn("test").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - } - - @Test - fun testDoReturnNullValue() { - val mock = mock() - - doReturn(null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnNullValues() { - val mock = mock() - - doReturn(null, null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnValues() { - val mock = mock() - - doReturn("test", "test2").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - expect(mock.stringResult()).toBe("test2") - } - - @Test - fun testDoThrowClass() { - val mock = mock() - - doThrow(IllegalStateException::class).whenever(mock).go() - - try { - mock.go() - throw AssertionError("Call should have thrown.") - } catch (e: IllegalStateException) { - } - } - - @Test - fun testDoThrow() { - val mock = mock() - - doThrow(IllegalStateException("test")).whenever(mock).go() - - expectErrorWithMessage("test").on { - mock.go() - } - } - - @Test - fun testMockStubbing_lambda() { - /* Given */ - val mock = mock() { - on { stringResult() } doReturn "A" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testMockStubbing_normalOverridesLambda() { - /* Given */ - val mock = mock() { - on { stringResult() }.doReturn("A") - } - whenever(mock.stringResult()).thenReturn("B") - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("B") - } - - @Test - fun testMockStubbing_methodCall() { - /* Given */ - val mock = mock() - mock { - on(mock.stringResult()).doReturn("A") - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testMockStubbing_builder() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() } doReturn mock - } - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBeTheSameAs(mock) - } - - @Test - fun testMockStubbing_nullable() { - /* Given */ - val mock = mock { - on { nullableStringResult() } doReturn "Test" - } - - /* When */ - val result = mock.nullableStringResult() - - /* Then */ - expect(result).toBe("Test") - } - - @Test - fun testMockStubbing_doThrow() { - /* Given */ - val mock = mock { - on { builderMethod() } doThrow IllegalArgumentException() - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - } - - @Test - fun testMockStubbing_doThrowClass() { - /* Given */ - val mock = mock { - on { builderMethod() } doThrow IllegalArgumentException::class - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - } - - @Test - fun testMockStubbing_doThrowVarargs() { - /* Given */ - val mock = mock { - on { builderMethod() }.doThrow(IllegalArgumentException(), UnsupportedOperationException()) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: UnsupportedOperationException) { - } - } - - @Test - fun testMockStubbing_doThrowClassVarargs() { - /* Given */ - val mock = mock { - on { builderMethod() }.doThrow(IllegalArgumentException::class, UnsupportedOperationException::class) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: UnsupportedOperationException) { - } - } - - @Test - fun testMockStubbing_doAnswer_lambda() { - /* Given */ - val mock = mock { - on { stringResult() } doAnswer { "result" } - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testMockStubbing_doAnswer_instance() { - /* Given */ - val mock = mock { - on { stringResult() } doAnswer Answer { "result" } - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testMockStubbing_doAnswer_returnsSelf() { - /* Given */ - val mock = mock { - on { builderMethod() } doAnswer Mockito.RETURNS_SELF - } - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBe(mock) - } - - @Test - fun testMockStubbing_doAnswer_withArgument() { - /* Given */ - val mock = mock { - on { stringResult(any()) } doAnswer { "${it.arguments[0]}-result" } - } - - /* When */ - val result = mock.stringResult("argument") - - /* Then */ - expect(result).toBe("argument-result") - } - - @Test - fun testMockStubbingAfterCreatingMock() { - val mock = mock() - - //create stub after creation of mock - mock.stub { - on { stringResult() } doReturn "result" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testOverrideDefaultStub() { - /* Given mock with stub */ - val mock = mock { - on { stringResult() } doReturn "result1" - } - - /* override stub */ - mock.stub { - on { stringResult() } doReturn "result2" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result2") - } - - @Test - fun mock_withCustomName() { - /* Given */ - val mock = mock("myName") - - /* Expect */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mock_withCustomDefaultAnswer() { - /* Given */ - val mock = mock(Mockito.RETURNS_SELF) - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBe(mock) - } - - @Test - fun mock_withCustomDefaultAnswer_parameterName() { - /* Given */ - val mock = mock(defaultAnswer = Mockito.RETURNS_SELF) - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBe(mock) - } - - @Test - fun mock_withSettings_extraInterfaces() { - /* Given */ - val mock = mock( - withSettings().extraInterfaces(ExtraInterface::class.java) - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettings_name() { - /* Given */ - val mock = mock( - withSettings().name("myName") - ) - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettings_defaultAnswer() { - /* Given */ - val mock = mock( - withSettings().defaultAnswer(RETURNS_MOCKS) - ) - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mock_withSettings_serializable() { - /* Given */ - val mock = mock( - withSettings().serializable() - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettings_serializableMode() { - /* Given */ - val mock = mock( - withSettings().serializable(BASIC) - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettings_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock( - withSettings().verboseLogging() - ) - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mock_withSettings_invocationListeners() { - /* Given */ - var bool = false - val mock = mock( - withSettings().invocationListeners(InvocationListener { bool = true }) - ) - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mock_withSettings_stubOnly() { - /* Given */ - val mock = mock( - withSettings().stubOnly() - ) - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettings_useConstructor() { - /* Expect */ - expectErrorWithMessage("Unable to create mock instance of type") on { - mock( - withSettings().useConstructor() - ) - } - } - - @Test - fun mock_withSettingsAPI_extraInterfaces() { - /* Given */ - val mock = mock( - extraInterfaces = arrayOf(ExtraInterface::class) - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_name() { - /* Given */ - val mock = mock(name = "myName") - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettingsAPI_defaultAnswer() { - /* Given */ - val mock = mock(defaultAnswer = RETURNS_MOCKS) - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mock_withSettingsAPI_serializable() { - /* Given */ - val mock = mock(serializable = true) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_serializableMode() { - /* Given */ - val mock = mock(serializableMode = BASIC) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock(verboseLogging = true) - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mock_withSettingsAPI_invocationListeners() { - /* Given */ - var bool = false - val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mock_withSettingsAPI_stubOnly() { - /* Given */ - val mock = mock(stubOnly = true) - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettingsAPI_useConstructor() { - /* Given */ - expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} - } - } - - @Test - fun mockStubbing_withSettingsAPI_extraInterfaces() { - /* Given */ - val mock = mock(extraInterfaces = arrayOf(ExtraInterface::class)) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_name() { - /* Given */ - val mock = mock(name = "myName") {} - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mockStubbing_withSettingsAPI_defaultAnswer() { - /* Given */ - val mock = mock(defaultAnswer = RETURNS_MOCKS) {} - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mockStubbing_withSettingsAPI_serializable() { - /* Given */ - val mock = mock(serializable = true) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_serializableMode() { - /* Given */ - val mock = mock(serializableMode = BASIC) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock(verboseLogging = true) {} - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mockStubbing_withSettingsAPI_invocationListeners() { - /* Given */ - var bool = false - val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) {} - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mockStubbing_withSettingsAPI_stubOnly() { - /* Given */ - val mock = mock(stubOnly = true) {} - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mockStubbing_withSettingsAPI_useConstructor() { - /* Given */ - expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} - } - } - - @Test - fun stubbingTwiceWithArgumentMatchers() { - /* When */ - val mock = mock { - on { stringResult(argThat { this == "A" }) } doReturn "A" - on { stringResult(argThat { this == "B" }) } doReturn "B" - } - - /* Then */ - expect(mock.stringResult("A")).toBe("A") - expect(mock.stringResult("B")).toBe("B") - } - - @Test - fun stubbingTwiceWithCheckArgumentMatchers_throwsException() { - /* Expect */ - expectErrorWithMessage("null").on { - mock { - on { stringResult(check { }) } doReturn "A" - on { stringResult(check { }) } doReturn "B" - } - } - } - - @Test - fun doReturn_withSingleItemList() { - /* Given */ - val mock = mock { - on { stringResult() } doReturn listOf("a", "b") - } - - /* Then */ - expect(mock.stringResult()).toBe("a") - expect(mock.stringResult()).toBe("b") - } - - @Test - fun doReturn_throwsNPE() { - expectErrorWithMessage("look at the stack trace below") on { - - /* When */ - mock { - on { throwsNPE() } doReturn "result" - } - } - } - - @Test - fun doReturn_withGenericIntReturnType_on() { - /* Expect */ - expectErrorWithMessage("onGeneric") on { - - /* When */ - mock> { - on { genericMethod() } doReturn 2 - } - } - } - - @Test - fun doReturn_withGenericIntReturnType_onGeneric() { - /* Given */ - val mock = mock> { - onGeneric { genericMethod() } doReturn 2 - } - - /* Then */ - expect(mock.genericMethod()).toBe(2) - } - - @Test - fun doReturn_withGenericNullableReturnType_onGeneric() { - val m = mock> { - onGeneric { nullableReturnType() } doReturn "Test" - } - - expect(m.nullableReturnType()).toBe("Test") - } - - @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 stubbingExistingMock() { - /* Given */ - val mock = mock() - - /* When */ - stubbing(mock) { - on { stringResult() } doReturn "result" - } - - /* Then */ - expect(mock.stringResult()).toBe("result") - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig b/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig deleted file mode 100644 index b06d453..0000000 --- a/mockito-kotlin/src/test/kotlin/test/MockitoTest.kt.orig +++ /dev/null @@ -1,1036 +0,0 @@ -package test - -import com.nhaarman.expect.* -import com.nhaarman.mockitokotlin2.* -import org.junit.Test -import org.mockito.Mockito -import org.mockito.Mockito.RETURNS_MOCKS -import org.mockito.exceptions.base.MockitoAssertionError -import org.mockito.exceptions.verification.WantedButNotInvoked -import org.mockito.listeners.InvocationListener -import org.mockito.mock.SerializableMode.BASIC -<<<<<<< HEAD -import org.mockito.stubbing.Answer -======= ->>>>>>> 91437b8... Improve error message on NPE in -import java.io.* - - -/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -@Suppress("DEPRECATION") -class MockitoTest : TestBase() { - - @Test - fun anyString() { - mock().apply { - string("") - verify(this).string(any()) - } - } - - @Test - fun anyClosedClass() { - mock().apply { - closed(Closed()) - verify(this).closed(any()) - } - } - - @Test - fun anyIntArray() { - mock().apply { - intArray(intArrayOf()) - verify(this).intArray(any()) - } - } - - @Test - fun anyClassArray() { - mock().apply { - closedArray(arrayOf(Closed())) - verify(this).closedArray(anyArray()) - } - } - - @Test - fun anyNullableClassArray() { - mock().apply { - closedNullableArray(arrayOf(Closed(), null)) - verify(this).closedNullableArray(anyArray()) - } - } - - @Test - fun anyStringVararg() { - mock().apply { - closedVararg(Closed(), Closed()) - verify(this).closedVararg(anyVararg()) - } - } - - @Test - fun anyNull_neverVerifiesAny() { - mock().apply { - nullableString(null) - verify(this, never()).nullableString(any()) - } - } - - @Test - fun anyNull_verifiesAnyOrNull() { - mock().apply { - nullableString(null) - verify(this).nullableString(anyOrNull()) - } - } - - /** 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 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 checkWithNullArgument_throwsError() { - mock().apply { - nullableString(null) - - expectErrorWithMessage("null").on { - verify(this).nullableString(check {}) - } - } - } - - @Test - fun atLeastXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atLeast(2)).string(any()) - } - } - - @Test - fun testAtLeastOnce() { - mock().apply { - string("") - string("") - - verify(this, atLeastOnce()).string(any()) - } - } - - @Test - fun atMostXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atMost(2)).string(any()) - } - } - - @Test - fun testCalls() { - mock().apply { - string("") - string("") - - inOrder(this).verify(this, calls(2)).string(any()) - } - } - - @Test - fun testInOrderWithLambda() { - /* Given */ - val a = mock<() -> Unit>() - val b = mock<() -> Unit>() - - /* When */ - b() - a() - - /* Then */ - inOrder(a, b) { - verify(b).invoke() - verify(a).invoke() - } - } - - @Test - fun testClearInvocations() { - val mock = mock().apply { - string("") - } - - clearInvocations(mock) - - verify(mock, never()).string(any()) - } - - @Test - fun testDescription() { - try { - mock().apply { - verify(this, description("Test")).string(any()) - } - throw AssertionError("Verify should throw Exception.") - } catch (e: MockitoAssertionError) { - expect(e.message).toContain("Test") - } - } - - @Test - fun testDoAnswer() { - val mock = mock() - - doAnswer { "Test" } - .whenever(mock) - .stringResult() - - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun testDoCallRealMethod() { - val mock = mock() - - doReturn("Test").whenever(mock).stringResult() - doCallRealMethod().whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("Default") - } - - @Test - fun testDoNothing() { - val spy = spy(Open()) - val array = intArrayOf(3) - - doNothing().whenever(spy).modifiesContents(array) - spy.modifiesContents(array) - - expect(array[0]).toBe(3) - } - - @Test - fun testDoReturnValue() { - val mock = mock() - - doReturn("test").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - } - - @Test - fun testDoReturnNullValue() { - val mock = mock() - - doReturn(null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnNullValues() { - val mock = mock() - - doReturn(null, null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnValues() { - val mock = mock() - - doReturn("test", "test2").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - expect(mock.stringResult()).toBe("test2") - } - - @Test - fun testDoThrowClass() { - val mock = mock() - - doThrow(IllegalStateException::class).whenever(mock).go() - - try { - mock.go() - throw AssertionError("Call should have thrown.") - } catch (e: IllegalStateException) { - } - } - - @Test - fun testDoThrow() { - val mock = mock() - - doThrow(IllegalStateException("test")).whenever(mock).go() - - expectErrorWithMessage("test").on { - mock.go() - } - } - - @Test - fun testMockStubbing_lambda() { - /* Given */ - val mock = mock() { - on { stringResult() } doReturn "A" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testMockStubbing_normalOverridesLambda() { - /* Given */ - val mock = mock() { - on { stringResult() }.doReturn("A") - } - whenever(mock.stringResult()).thenReturn("B") - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("B") - } - - @Test - fun testMockStubbing_methodCall() { - /* Given */ - val mock = mock() - mock { - on(mock.stringResult()).doReturn("A") - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testMockStubbing_builder() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() } doReturn mock - } - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBeTheSameAs(mock) - } - - @Test - fun testMockStubbing_nullable() { - /* Given */ - val mock = mock { - on { nullableStringResult() } doReturn "Test" - } - - /* When */ - val result = mock.nullableStringResult() - - /* Then */ - expect(result).toBe("Test") - } - - @Test - fun testMockStubbing_doThrow() { - /* Given */ - val mock = mock { - on { builderMethod() } doThrow IllegalArgumentException() - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - } - - @Test - fun testMockStubbing_doThrowClass() { - /* Given */ - val mock = mock { - on { builderMethod() } doThrow IllegalArgumentException::class - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - } - - @Test - fun testMockStubbing_doThrowVarargs() { - /* Given */ - val mock = mock { - on { builderMethod() }.doThrow(IllegalArgumentException(), UnsupportedOperationException()) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: UnsupportedOperationException) { - } - } - - @Test - fun testMockStubbing_doThrowClassVarargs() { - /* Given */ - val mock = mock { - on { builderMethod() }.doThrow(IllegalArgumentException::class, UnsupportedOperationException::class) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: UnsupportedOperationException) { - } - } - - @Test - fun testMockStubbing_doAnswer_lambda() { - /* Given */ - val mock = mock { - on { stringResult() } doAnswer { "result" } - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testMockStubbing_doAnswer_instance() { - /* Given */ - val mock = mock { - on { stringResult() } doAnswer Answer { "result" } - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - - @Test - fun testMockStubbing_doAnswer_withArgument() { - /* Given */ - val mock = mock { - on { stringResult(any()) } doAnswer { "${it.arguments[0]}-result" } - } - - /* When */ - val result = mock.stringResult("argument") - - /* Then */ - expect(result).toBe("argument-result") - } - - @Test - fun testMockStubbingAfterCreatingMock() { - val mock = mock() - - //create stub after creation of mock - mock.stub { - on { stringResult() } doReturn "result" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testOverrideDefaultStub() { - /* Given mock with stub */ - val mock = mock { - on { stringResult() } doReturn "result1" - } - - /* override stub */ - mock.stub { - on { stringResult() } doReturn "result2" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result2") - } - - @Test - fun mock_withCustomName() { - /* Given */ - val mock = mock("myName") - - /* Expect */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mock_withCustomDefaultAnswer() { - /* Given */ - val mock = mock(Mockito.RETURNS_SELF) - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBe(mock) - } - - @Test - fun mock_withCustomDefaultAnswer_parameterName() { - /* Given */ - val mock = mock(defaultAnswer = Mockito.RETURNS_SELF) - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBe(mock) - } - - @Test - fun mock_withSettings_extraInterfaces() { - /* Given */ - val mock = mock( - withSettings().extraInterfaces(ExtraInterface::class.java) - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettings_name() { - /* Given */ - val mock = mock( - withSettings().name("myName") - ) - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettings_defaultAnswer() { - /* Given */ - val mock = mock( - withSettings().defaultAnswer(RETURNS_MOCKS) - ) - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mock_withSettings_serializable() { - /* Given */ - val mock = mock( - withSettings().serializable() - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettings_serializableMode() { - /* Given */ - val mock = mock( - withSettings().serializable(BASIC) - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettings_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock( - withSettings().verboseLogging() - ) - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mock_withSettings_invocationListeners() { - /* Given */ - var bool = false - val mock = mock( - withSettings().invocationListeners(InvocationListener { bool = true }) - ) - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mock_withSettings_stubOnly() { - /* Given */ - val mock = mock( - withSettings().stubOnly() - ) - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettings_useConstructor() { - /* Expect */ - expectErrorWithMessage("Unable to create mock instance of type") on { - mock( - withSettings().useConstructor() - ) - } - } - - @Test - fun mock_withSettingsAPI_extraInterfaces() { - /* Given */ - val mock = mock( - extraInterfaces = arrayOf(ExtraInterface::class) - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_name() { - /* Given */ - val mock = mock(name = "myName") - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettingsAPI_defaultAnswer() { - /* Given */ - val mock = mock(defaultAnswer = RETURNS_MOCKS) - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mock_withSettingsAPI_serializable() { - /* Given */ - val mock = mock(serializable = true) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_serializableMode() { - /* Given */ - val mock = mock(serializableMode = BASIC) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock(verboseLogging = true) - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mock_withSettingsAPI_invocationListeners() { - /* Given */ - var bool = false - val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mock_withSettingsAPI_stubOnly() { - /* Given */ - val mock = mock(stubOnly = true) - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettingsAPI_useConstructor() { - /* Given */ - expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} - } - } - - @Test - fun mockStubbing_withSettingsAPI_extraInterfaces() { - /* Given */ - val mock = mock(extraInterfaces = arrayOf(ExtraInterface::class)) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_name() { - /* Given */ - val mock = mock(name = "myName") {} - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mockStubbing_withSettingsAPI_defaultAnswer() { - /* Given */ - val mock = mock(defaultAnswer = RETURNS_MOCKS) {} - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mockStubbing_withSettingsAPI_serializable() { - /* Given */ - val mock = mock(serializable = true) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_serializableMode() { - /* Given */ - val mock = mock(serializableMode = BASIC) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock(verboseLogging = true) {} - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mockStubbing_withSettingsAPI_invocationListeners() { - /* Given */ - var bool = false - val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) {} - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mockStubbing_withSettingsAPI_stubOnly() { - /* Given */ - val mock = mock(stubOnly = true) {} - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mockStubbing_withSettingsAPI_useConstructor() { - /* Given */ - expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} - } - } - - @Test - fun stubbingTwiceWithArgumentMatchers() { - /* When */ - val mock = mock { - on { stringResult(argThat { this == "A" }) } doReturn "A" - on { stringResult(argThat { this == "B" }) } doReturn "B" - } - - /* Then */ - expect(mock.stringResult("A")).toBe("A") - expect(mock.stringResult("B")).toBe("B") - } - - @Test - fun stubbingTwiceWithCheckArgumentMatchers_throwsException() { - /* Expect */ - expectErrorWithMessage("null").on { - mock { - on { stringResult(check { }) } doReturn "A" - on { stringResult(check { }) } doReturn "B" - } - } - } - - @Test - fun doReturn_withSingleItemList() { - /* Given */ - val mock = mock { - on { stringResult() } doReturn listOf("a", "b") - } - - /* Then */ - expect(mock.stringResult()).toBe("a") - expect(mock.stringResult()).toBe("b") - } - - @Test - fun doReturn_throwsNPE() { - expectErrorWithMessage("look at the stack trace below") on { - - /* When */ - mock { - on { throwsNPE() } doReturn "result" - } - } - } - - @Test - fun doReturn_withGenericIntReturnType_on() { - /* Expect */ - expectErrorWithMessage("onGeneric") on { - - /* When */ - mock> { - on { genericMethod() } doReturn 2 - } - } - } - - @Test - fun doReturn_withGenericIntReturnType_onGeneric() { - /* Given */ - val mock = mock> { - onGeneric { genericMethod() } doReturn 2 - } - - /* Then */ - expect(mock.genericMethod()).toBe(2) - } - - @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)) - } - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt b/mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt new file mode 100644 index 0000000..25371c1 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt @@ -0,0 +1,320 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.expect.fail +import com.nhaarman.mockitokotlin2.* +import org.junit.Test +import org.mockito.Mockito +import org.mockito.stubbing.Answer + +class OngoingStubbingTest : TestBase() { + + @Test + fun testOngoingStubbing_methodCall() { + /* Given */ + val mock = mock() + mock { + on(mock.stringResult()).doReturn("A") + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testOngoingStubbing_builder() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doReturn mock + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBeTheSameAs(mock) + } + + @Test + fun testOngoingStubbing_nullable() { + /* Given */ + val mock = mock { + on { nullableStringResult() } doReturn "Test" + } + + /* When */ + val result = mock.nullableStringResult() + + /* Then */ + expect(result).toBe("Test") + } + + @Test + fun testOngoingStubbing_doThrow() { + /* Given */ + val mock = mock { + on { builderMethod() } doThrow IllegalArgumentException() + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + } + + @Test + fun testOngoingStubbing_doThrowClass() { + /* Given */ + val mock = mock { + on { builderMethod() } doThrow IllegalArgumentException::class + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + } + + @Test + fun testOngoingStubbing_doThrowVarargs() { + /* Given */ + val mock = mock { + on { builderMethod() }.doThrow( + IllegalArgumentException(), + UnsupportedOperationException() + ) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: UnsupportedOperationException) { + } + } + + @Test + fun testOngoingStubbing_doThrowClassVarargs() { + /* Given */ + val mock = mock { + on { builderMethod() }.doThrow( + IllegalArgumentException::class, + UnsupportedOperationException::class + ) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: UnsupportedOperationException) { + } + } + + @Test + fun testOngoingStubbing_doAnswer_lambda() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOngoingStubbing_doAnswer_instance() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer Answer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOngoingStubbing_doAnswer_returnsSelf() { + /* Given */ + val mock = mock { + on { builderMethod() } doAnswer Mockito.RETURNS_SELF + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun testOngoingStubbing_doAnswer_withArgument() { + /* Given */ + val mock = mock { + on { stringResult(any()) } doAnswer { "${it.arguments[0]}-result" } + } + + /* When */ + val result = mock.stringResult("argument") + + /* Then */ + expect(result).toBe("argument-result") + } + + @Test + fun testMockStubbingAfterCreatingMock() { + val mock = mock() + + //create stub after creation of mock + mock.stub { + on { stringResult() } doReturn "result" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOverrideDefaultStub() { + /* Given mock with stub */ + val mock = mock { + on { stringResult() } doReturn "result1" + } + + /* override stub */ + mock.stub { + on { stringResult() } doReturn "result2" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result2") + } + + + @Test + fun stubbingTwiceWithArgumentMatchers() { + /* When */ + val mock = mock { + on { stringResult(argThat { this == "A" }) } doReturn "A" + on { stringResult(argThat { this == "B" }) } doReturn "B" + } + + /* Then */ + expect(mock.stringResult("A")).toBe("A") + expect(mock.stringResult("B")).toBe("B") + } + + @Test + fun stubbingTwiceWithCheckArgumentMatchers_throwsException() { + /* Expect */ + expectErrorWithMessage("null").on { + mock { + on { stringResult(check { }) } doReturn "A" + on { stringResult(check { }) } doReturn "B" + } + } + } + + @Test + fun doReturn_withSingleItemList() { + /* Given */ + val mock = mock { + on { stringResult() } doReturn listOf("a", "b") + } + + /* Then */ + expect(mock.stringResult()).toBe("a") + expect(mock.stringResult()).toBe("b") + } + + @Test + fun doReturn_throwsNPE() { + expectErrorWithMessage("look at the stack trace below") on { + + /* When */ + mock { + on { throwsNPE() } doReturn "result" + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_on() { + /* Expect */ + expectErrorWithMessage("onGeneric") on { + + /* When */ + mock> { + on { genericMethod() } doReturn 2 + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_onGeneric() { + /* Given */ + val mock = mock> { + onGeneric { genericMethod() } doReturn 2 + } + + /* Then */ + expect(mock.genericMethod()).toBe(2) + } + + @Test + fun doReturn_withGenericNullableReturnType_onGeneric() { + val m = mock> { + onGeneric { nullableReturnType() } doReturn "Test" + } + + expect(m.nullableReturnType()).toBe("Test") + } + + @Test + fun stubbingExistingMock() { + /* Given */ + val mock = mock() + + /* When */ + stubbing(mock) { + on { stringResult() } doReturn "result" + } + + /* Then */ + expect(mock.stringResult()).toBe("result") + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/StubberTest.kt b/mockito-kotlin/src/test/kotlin/test/StubberTest.kt new file mode 100644 index 0000000..0e7ce65 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/StubberTest.kt @@ -0,0 +1,103 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockitokotlin2.* +import org.junit.Test + +class StubberTest : TestBase() { + + @Test + fun testDoAnswer() { + val mock = mock() + + doAnswer { "Test" } + .whenever(mock) + .stringResult() + + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun testDoCallRealMethod() { + val mock = mock() + + doReturn("Test").whenever(mock).stringResult() + doCallRealMethod().whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("Default") + } + + @Test + fun testDoNothing() { + val spy = spy(Open()) + val array = intArrayOf(3) + + doNothing().whenever(spy).modifiesContents(array) + spy.modifiesContents(array) + + expect(array[0]).toBe(3) + } + + @Test + fun testDoReturnValue() { + val mock = mock() + + doReturn("test").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + } + + @Test + fun testDoReturnNullValue() { + val mock = mock() + + doReturn(null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnNullValues() { + val mock = mock() + + doReturn(null, null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnValues() { + val mock = mock() + + doReturn("test", "test2").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + expect(mock.stringResult()).toBe("test2") + } + + @Test + fun testDoThrowClass() { + val mock = mock() + + doThrow(IllegalStateException::class).whenever(mock).go() + + try { + mock.go() + throw AssertionError("Call should have thrown.") + } catch (e: IllegalStateException) { + } + } + + @Test + fun testDoThrow() { + val mock = mock() + + doThrow(IllegalStateException("test")).whenever(mock).go() + + expectErrorWithMessage("test").on { + mock.go() + } + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/VerificationTest.kt b/mockito-kotlin/src/test/kotlin/test/VerificationTest.kt new file mode 100644 index 0000000..5a3bf39 --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/VerificationTest.kt @@ -0,0 +1,89 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.* +import org.junit.Test +import org.mockito.exceptions.base.MockitoAssertionError + +class VerificationTest : TestBase() { + + @Test + fun atLeastXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atLeast(2)).string(any()) + } + } + + @Test + fun testAtLeastOnce() { + mock().apply { + string("") + string("") + + verify(this, atLeastOnce()).string(any()) + } + } + + @Test + fun atMostXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atMost(2)).string(any()) + } + } + + @Test + fun testCalls() { + mock().apply { + string("") + string("") + + inOrder(this).verify(this, calls(2)).string(any()) + } + } + + @Test + fun testInOrderWithLambda() { + /* Given */ + val a = mock<() -> Unit>() + val b = mock<() -> Unit>() + + /* When */ + b() + a() + + /* Then */ + inOrder(a, b) { + verify(b).invoke() + verify(a).invoke() + } + } + + @Test + fun testClearInvocations() { + val mock = mock().apply { + string("") + } + + clearInvocations(mock) + + verify(mock, never()).string(any()) + } + + @Test + fun testDescription() { + try { + mock().apply { + verify(this, description("Test")).string(any()) + } + throw AssertionError("Verify should throw Exception.") + } catch (e: MockitoAssertionError) { + expect(e.message).toContain("Test") + } + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt index 16fb293..b214fcc 100644 --- a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt @@ -1,19 +1,17 @@ package test.createinstance import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.internal.NullCaster +import com.nhaarman.mockitokotlin2.internal.createInstance import org.junit.Test import test.TestBase class NullCasterTest : TestBase() { - private val nullCaster = NullCaster() - @Test fun createInstance() { /* When */ - val result = nullCaster.createInstance(String::class) + val result = createInstance(String::class) /* Then */ expect(result).toBeNull() @@ -22,7 +20,7 @@ class NullCasterTest : TestBase() { @Test fun kotlinAcceptsNullValue() { /* Given */ - val s: String = nullCaster.createInstance(String::class) + val s: String = createInstance(String::class) /* When */ acceptNonNullableString(s) -- cgit v1.2.3 From 5c034d4ff70ea9afb589a00918821026cadfcdac Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 21 Jan 2018 17:08:25 +0100 Subject: Move tests to separate module --- .travis.yml | 11 +- mockito-kotlin/build.gradle | 31 +- .../nhaarman/mockitokotlin2/internal/MockMaker.kt | 35 --- .../src/test/kotlin/test/ArgumentCaptorTest.kt | 120 -------- .../src/test/kotlin/test/BDDMockitoTest.kt | 103 ------- mockito-kotlin/src/test/kotlin/test/Classes.kt | 83 ------ mockito-kotlin/src/test/kotlin/test/EqTest.kt | 101 ------- .../src/test/kotlin/test/MatchersTest.kt | 183 ------------ mockito-kotlin/src/test/kotlin/test/MockingTest.kt | 325 --------------------- .../src/test/kotlin/test/OngoingStubbingTest.kt | 320 -------------------- mockito-kotlin/src/test/kotlin/test/SpyTest.kt | 119 -------- mockito-kotlin/src/test/kotlin/test/StubberTest.kt | 103 ------- mockito-kotlin/src/test/kotlin/test/TestBase.kt | 18 -- .../src/test/kotlin/test/VerificationTest.kt | 89 ------ mockito-kotlin/src/test/kotlin/test/VerifyTest.kt | 58 ---- .../kotlin/test/createinstance/NullCasterTest.kt | 31 -- .../kotlin/test/inline/UsingMockMakerInlineTest.kt | 120 -------- ops/mockMakerInline.sh | 11 + ops/org.mockito.plugins.MockMaker | 1 + settings.gradle | 1 + tests/README.md | 7 + tests/build.gradle | 29 ++ tests/src/test/kotlin/test/ArgumentCaptorTest.kt | 120 ++++++++ tests/src/test/kotlin/test/BDDMockitoTest.kt | 103 +++++++ tests/src/test/kotlin/test/Classes.kt | 83 ++++++ tests/src/test/kotlin/test/EqTest.kt | 101 +++++++ tests/src/test/kotlin/test/MatchersTest.kt | 183 ++++++++++++ tests/src/test/kotlin/test/MockMaker.kt | 10 + tests/src/test/kotlin/test/MockingTest.kt | 325 +++++++++++++++++++++ tests/src/test/kotlin/test/OngoingStubbingTest.kt | 322 ++++++++++++++++++++ tests/src/test/kotlin/test/SpyTest.kt | 119 ++++++++ tests/src/test/kotlin/test/StubberTest.kt | 103 +++++++ tests/src/test/kotlin/test/TestBase.kt | 11 + tests/src/test/kotlin/test/VerificationTest.kt | 89 ++++++ tests/src/test/kotlin/test/VerifyTest.kt | 58 ++++ .../kotlin/test/createinstance/NullCasterTest.kt | 31 ++ .../kotlin/test/inline/UsingMockMakerInlineTest.kt | 116 ++++++++ 37 files changed, 1832 insertions(+), 1841 deletions(-) delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/Classes.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/EqTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/MatchersTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/MockingTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/SpyTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/StubberTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/TestBase.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/VerificationTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/VerifyTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt delete mode 100644 mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt create mode 100755 ops/mockMakerInline.sh create mode 100644 ops/org.mockito.plugins.MockMaker create mode 100644 tests/README.md create mode 100644 tests/build.gradle create mode 100644 tests/src/test/kotlin/test/ArgumentCaptorTest.kt create mode 100644 tests/src/test/kotlin/test/BDDMockitoTest.kt create mode 100644 tests/src/test/kotlin/test/Classes.kt create mode 100644 tests/src/test/kotlin/test/EqTest.kt create mode 100644 tests/src/test/kotlin/test/MatchersTest.kt create mode 100644 tests/src/test/kotlin/test/MockMaker.kt create mode 100644 tests/src/test/kotlin/test/MockingTest.kt create mode 100644 tests/src/test/kotlin/test/OngoingStubbingTest.kt create mode 100644 tests/src/test/kotlin/test/SpyTest.kt create mode 100644 tests/src/test/kotlin/test/StubberTest.kt create mode 100644 tests/src/test/kotlin/test/TestBase.kt create mode 100644 tests/src/test/kotlin/test/VerificationTest.kt create mode 100644 tests/src/test/kotlin/test/VerifyTest.kt create mode 100644 tests/src/test/kotlin/test/createinstance/NullCasterTest.kt create mode 100644 tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt diff --git a/.travis.yml b/.travis.yml index 89bb8fa..eeeabb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,13 +9,13 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.10 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.20 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.2.10 + env: TERM=dumb KOTLIN_VERSION=1.2.20 env: @@ -26,7 +26,10 @@ install: - true script: - - ./gradlew test + - ops/mockMakerInline.sh + - ./gradlew clean + - ./gradlew assemble + - ./gradlew test -i notifications: - email: false \ No newline at end of file + email: false diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 0464934..e5d1d25 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.7' + ext.kotlin_version = "1.2.20" repositories { mavenCentral() @@ -24,12 +24,8 @@ repositories { } dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.mockito:mockito-core:2.13.0" - - /* Tests */ - testCompile "junit:junit:4.12" - testCompile "com.nhaarman:expect.kt:1.0.0" } dokka { @@ -43,26 +39,3 @@ dokka { } } javadoc.dependsOn dokka - -//Switch inline -task createTestResources { - def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") - if (System.env.MOCK_MAKER != null) { - logger.warn("! Using MockMaker ${System.env.MOCK_MAKER}") - mockMakerFile.parentFile.mkdirs() - mockMakerFile.createNewFile() - mockMakerFile.write(System.env.MOCK_MAKER) - } else { - logger.warn("! Using default MockMaker") - } -} - -task removeTestResources { - def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") - if (mockMakerFile.exists()) { - mockMakerFile.delete() - } -} - -test.dependsOn createTestResources -test.finalizedBy removeTestResources diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt deleted file mode 100644 index 307f3dc..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/MockMaker.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2.internal - -import org.mockito.internal.configuration.plugins.Plugins -import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker - -internal var mockMakerInlineEnabled: Boolean? = null -internal fun mockMakerInlineEnabled(): Boolean { - return mockMakerInlineEnabled ?: - Plugins.getMockMaker() is InlineByteBuddyMockMaker -} diff --git a/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt b/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt deleted file mode 100644 index 551cc6b..0000000 --- a/mockito-kotlin/src/test/kotlin/test/ArgumentCaptorTest.kt +++ /dev/null @@ -1,120 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* -import org.junit.Test -import java.util.* - -class ArgumentCaptorTest : TestBase() { - - @Test - fun argumentCaptor_withSingleValue() { - /* Given */ - val date: Date = mock() - - /* When */ - date.time = 5L - - /* Then */ - val captor = argumentCaptor() - verify(date).time = captor.capture() - expect(captor.lastValue).toBe(5L) - } - - @Test - fun argumentCaptor_withNullValue_usingNonNullable() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.nullableString(null) - - /* Then */ - val captor = argumentCaptor() - verify(m).nullableString(captor.capture()) - expect(captor.lastValue).toBeNull() - } - - @Test - fun argumentCaptor_withNullValue_usingNullable() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.nullableString(null) - - /* Then */ - val captor = nullableArgumentCaptor() - verify(m).nullableString(captor.capture()) - expect(captor.lastValue).toBeNull() - } - - @Test - fun argumentCaptor_multipleValues() { - /* Given */ - val date: Date = mock() - - /* When */ - date.time = 5L - date.time = 7L - - /* Then */ - val captor = argumentCaptor() - 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() - verify(m, times(2)).nullableString(captor.capture()) - expect(captor.allValues).toBe(listOf("test", null)) - } - - @Test - fun argumentCaptor_callProperties() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.int(1) - m.int(2) - m.int(3) - m.int(4) - m.int(5) - - /* Then */ - argumentCaptor().apply { - verify(m, times(5)).int(capture()) - - expect(firstValue).toBe(1) - expect(secondValue).toBe(2) - expect(thirdValue).toBe(3) - expect(lastValue).toBe(5) - } - } - - @Test(expected = IndexOutOfBoundsException::class) - fun argumentCaptor_callPropertyNotAvailable() { - /* Given */ - val m: Methods = mock() - - /* When */ - m.int(1) - - /* Then */ - argumentCaptor().apply { - verify(m).int(capture()) - - expect(secondValue).toBe(2) - } - } -} diff --git a/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt b/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt deleted file mode 100644 index ded1462..0000000 --- a/mockito-kotlin/src/test/kotlin/test/BDDMockitoTest.kt +++ /dev/null @@ -1,103 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* -import org.junit.Test - -class BDDMockitoTest { - - @Test - fun given_willReturn_properlyStubs() { - /* Given */ - val mock = mock() - - /* When */ - given(mock.stringResult()).willReturn("Test") - - /* Then */ - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun givenLambda_willReturn_properlyStubs() { - /* Given */ - val mock = mock() - - /* When */ - given { mock.stringResult() }.willReturn("Test") - - /* Then */ - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun given_willReturnLambda_properlyStubs() { - /* Given */ - val mock = mock() - - /* When */ - given(mock.stringResult()).willReturn { "Test" } - - /* Then */ - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun givenLambda_willReturnLambda_properlyStubs() { - /* Given */ - val mock = mock() - - /* When */ - given { mock.stringResult() } willReturn { "Test" } - - /* Then */ - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun given_willAnswer_properlyStubs() { - /* Given */ - val mock = mock() - - /* When */ - given(mock.stringResult()).willAnswer { "Test" } - - /* Then */ - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun given_willAnswerInfix_properlyStubs() { - /* Given */ - val mock = mock() - - /* When */ - given(mock.stringResult()) willAnswer { "Test" } - - /* Then */ - expect(mock.stringResult()).toBe("Test") - } - - @Test(expected = IllegalStateException::class) - fun given_willThrowInfix_properlyStubs() { - /* Given */ - val mock = mock() - - /* When */ - given(mock.stringResult()) willThrow { IllegalStateException() } - mock.stringResult() - } - - @Test - fun then() { - /* Given */ - val mock = mock() - whenever(mock.stringResult()).thenReturn("Test") - - /* When */ - mock.stringResult() - - /* Then */ - then(mock).should().stringResult() - } -} diff --git a/mockito-kotlin/src/test/kotlin/test/Classes.kt b/mockito-kotlin/src/test/kotlin/test/Classes.kt deleted file mode 100644 index cfbb7ab..0000000 --- a/mockito-kotlin/src/test/kotlin/test/Classes.kt +++ /dev/null @@ -1,83 +0,0 @@ -package test - -/* -* The MIT License -* -* Copyright (c) 2016 Niek Haarman -* Copyright (c) 2007 Mockito contributors -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -open class Open { - open fun go(vararg arg: Any?) { - } - - open fun modifiesContents(a: IntArray) { - for (i in 0..a.size - 1) { - a[i] = a[i] + 1 - } - } - - open fun stringResult() = "Default" - - fun throwsNPE(): Any = throw NullPointerException("Test") -} - -class Closed - -interface Methods { - - fun intArray(i: IntArray) - fun closed(c: Closed) - fun closedArray(a: Array) - fun closedNullableArray(a: Array) - fun closedCollection(c: Collection) - fun closedList(c: List) - fun closedStringMap(m: Map) - fun closedSet(s: Set) - fun string(s: String) - fun int(i: Int) - fun closedVararg(vararg c: Closed) - fun throwableClass(t: ThrowableClass) - fun nullableString(s: String?) - - fun stringResult(): String - fun stringResult(s: String): String - fun nullableStringResult(): String? - fun builderMethod(): Methods - - fun nonDefaultReturnType(): ExtraInterface -} - -interface ExtraInterface - -abstract class ThrowingConstructor { - - constructor() { - error("Error in constructor") - } -} - -interface GenericMethods { - fun genericMethod(): T - fun nullableReturnType(): T? -} - -class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/mockito-kotlin/src/test/kotlin/test/EqTest.kt b/mockito-kotlin/src/test/kotlin/test/EqTest.kt deleted file mode 100644 index c070d95..0000000 --- a/mockito-kotlin/src/test/kotlin/test/EqTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -package test/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.eq -import com.nhaarman.mockitokotlin2.mock -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.mockito.Mockito - -class EqTest : TestBase() { - - private val interfaceInstance: MyInterface = MyClass() - private val openClassInstance: MyClass = MyClass() - private val closedClassInstance: ClosedClass = ClosedClass() - - private lateinit var doAnswer: Open - - @Before - override fun setup() { - super.setup() - - /* Create a proper Mockito state */ - doAnswer = Mockito.doAnswer { }.`when`(mock()) - } - - @After - override fun tearDown() { - super.tearDown() - - /* Close `any` Mockito state */ - doAnswer.go(0) - } - - @Test - fun eqInterfaceInstance() { - /* When */ - val result = eq(interfaceInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun eqOpenClassInstance() { - /* When */ - val result = eq(openClassInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun eqClosedClassInstance() { - /* When */ - val result = eq(closedClassInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun nullArgument() { - /* Given */ - val s: String? = null - - /* When */ - val result = eq(s) - - /* Then */ - expect(result).toBeNull() - } - - private interface MyInterface - private open class MyClass : MyInterface - class ClosedClass -} - diff --git a/mockito-kotlin/src/test/kotlin/test/MatchersTest.kt b/mockito-kotlin/src/test/kotlin/test/MatchersTest.kt deleted file mode 100644 index 312d7a0..0000000 --- a/mockito-kotlin/src/test/kotlin/test/MatchersTest.kt +++ /dev/null @@ -1,183 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockitokotlin2.* -import org.junit.Test -import java.io.IOException - -class MatchersTest : TestBase() { - - @Test - fun anyString() { - mock().apply { - string("") - verify(this).string(any()) - } - } - - @Test - fun anyClosedClass() { - mock().apply { - closed(Closed()) - verify(this).closed(any()) - } - } - - @Test - fun anyIntArray() { - mock().apply { - intArray(intArrayOf()) - verify(this).intArray(any()) - } - } - - @Test - fun anyClassArray() { - mock().apply { - closedArray(arrayOf(Closed())) - verify(this).closedArray(anyArray()) - } - } - - @Test - fun anyNullableClassArray() { - mock().apply { - closedNullableArray(arrayOf(Closed(), null)) - verify(this).closedNullableArray(anyArray()) - } - } - - @Test - fun anyStringVararg() { - mock().apply { - closedVararg(Closed(), Closed()) - verify(this).closedVararg(anyVararg()) - } - } - - @Test - fun anyNull_neverVerifiesAny() { - mock().apply { - nullableString(null) - verify(this, never()).nullableString(any()) - } - } - - @Test - fun anyNull_verifiesAnyOrNull() { - mock().apply { - nullableString(null) - verify(this).nullableString(anyOrNull()) - } - } - - /** 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 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 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)) - } - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/MockingTest.kt b/mockito-kotlin/src/test/kotlin/test/MockingTest.kt deleted file mode 100644 index 0d5730b..0000000 --- a/mockito-kotlin/src/test/kotlin/test/MockingTest.kt +++ /dev/null @@ -1,325 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.expect.fail -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever -import org.junit.Test -import org.mockito.Mockito -import org.mockito.exceptions.verification.WantedButNotInvoked -import org.mockito.listeners.InvocationListener -import org.mockito.mock.SerializableMode.BASIC -import java.io.PrintStream -import java.io.Serializable -import java.util.* - -class MockingTest : TestBase() { - - private lateinit var propertyInterfaceVariable: MyInterface - private lateinit var propertyClassVariable: MyClass - - @Test - fun localInterfaceValue() { - /* When */ - val instance: MyInterface = mock() - - /* Then */ - expect(instance).toNotBeNull() - } - - @Test - fun propertyInterfaceVariable() { - /* When */ - propertyInterfaceVariable = mock() - - /* Then */ - expect(propertyInterfaceVariable).toNotBeNull() - } - - @Test - fun localClassValue() { - /* When */ - val instance: MyClass = mock() - - /* Then */ - expect(instance).toNotBeNull() - } - - @Test - fun propertyClassVariable() { - /* When */ - propertyClassVariable = mock() - - /* Then */ - expect(propertyClassVariable).toNotBeNull() - } - - @Test - fun untypedVariable() { - /* When */ - val instance = mock() - - expect(instance).toNotBeNull() - } - - @Test - fun deepStubs() { - val cal: Calendar = mock(defaultAnswer = Mockito.RETURNS_DEEP_STUBS) - whenever(cal.time.time).thenReturn(123L) - expect(cal.time.time).toBe(123L) - } - - - @Test - fun testMockStubbing_lambda() { - /* Given */ - val mock = mock() { - on { stringResult() } doReturn "A" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testMockStubbing_normalOverridesLambda() { - /* Given */ - val mock = mock() { - on { stringResult() }.doReturn("A") - } - whenever(mock.stringResult()).thenReturn("B") - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("B") - } - - - - @Test - fun mock_withCustomDefaultAnswer_parameterName() { - /* Given */ - val mock = mock(defaultAnswer = Mockito.RETURNS_SELF) - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBe(mock) - } - - @Test - fun mock_withSettingsAPI_extraInterfaces() { - /* Given */ - val mock = mock( - extraInterfaces = arrayOf(ExtraInterface::class) - ) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_name() { - /* Given */ - val mock = mock(name = "myName") - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettingsAPI_defaultAnswer() { - /* Given */ - val mock = mock(defaultAnswer = Mockito.RETURNS_MOCKS) - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mock_withSettingsAPI_serializable() { - /* Given */ - val mock = mock(serializable = true) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_serializableMode() { - /* Given */ - val mock = mock(serializableMode = BASIC) - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mock_withSettingsAPI_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock(verboseLogging = true) - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mock_withSettingsAPI_invocationListeners() { - /* Given */ - var bool = false - val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mock_withSettingsAPI_stubOnly() { - /* Given */ - val mock = mock(stubOnly = true) - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mock_withSettingsAPI_useConstructor() { - /* Given */ - expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} - } - } - - @Test - fun mockStubbing_withSettingsAPI_extraInterfaces() { - /* Given */ - val mock = mock(extraInterfaces = arrayOf(ExtraInterface::class)) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_name() { - /* Given */ - val mock = mock(name = "myName") {} - - /* When */ - expectErrorWithMessage("myName.stringResult()") on { - verify(mock).stringResult() - } - } - - @Test - fun mockStubbing_withSettingsAPI_defaultAnswer() { - /* Given */ - val mock = mock(defaultAnswer = Mockito.RETURNS_MOCKS) {} - - /* When */ - val result = mock.nonDefaultReturnType() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun mockStubbing_withSettingsAPI_serializable() { - /* Given */ - val mock = mock(serializable = true) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_serializableMode() { - /* Given */ - val mock = mock(serializableMode = BASIC) {} - - /* Then */ - expect(mock).toBeInstanceOf() - } - - @Test - fun mockStubbing_withSettingsAPI_verboseLogging() { - /* Given */ - val out = mock() - System.setOut(out) - val mock = mock(verboseLogging = true) {} - - try { - /* When */ - verify(mock).stringResult() - fail("Expected an exception") - } catch (e: WantedButNotInvoked) { - /* Then */ - verify(out).println("methods.stringResult();") - } - } - - @Test - fun mockStubbing_withSettingsAPI_invocationListeners() { - /* Given */ - var bool = false - val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) {} - - /* When */ - mock.stringResult() - - /* Then */ - expect(bool).toHold() - } - - @Test - fun mockStubbing_withSettingsAPI_stubOnly() { - /* Given */ - val mock = mock(stubOnly = true) {} - - /* Expect */ - expectErrorWithMessage("is a stubOnly() mock") on { - - /* When */ - verify(mock).stringResult() - } - } - - @Test - fun mockStubbing_withSettingsAPI_useConstructor() { - /* Given */ - expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} - } - } - - private interface MyInterface - private open class MyClass -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt b/mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt deleted file mode 100644 index 25371c1..0000000 --- a/mockito-kotlin/src/test/kotlin/test/OngoingStubbingTest.kt +++ /dev/null @@ -1,320 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.expect.fail -import com.nhaarman.mockitokotlin2.* -import org.junit.Test -import org.mockito.Mockito -import org.mockito.stubbing.Answer - -class OngoingStubbingTest : TestBase() { - - @Test - fun testOngoingStubbing_methodCall() { - /* Given */ - val mock = mock() - mock { - on(mock.stringResult()).doReturn("A") - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("A") - } - - @Test - fun testOngoingStubbing_builder() { - /* Given */ - val mock = mock { mock -> - on { builderMethod() } doReturn mock - } - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBeTheSameAs(mock) - } - - @Test - fun testOngoingStubbing_nullable() { - /* Given */ - val mock = mock { - on { nullableStringResult() } doReturn "Test" - } - - /* When */ - val result = mock.nullableStringResult() - - /* Then */ - expect(result).toBe("Test") - } - - @Test - fun testOngoingStubbing_doThrow() { - /* Given */ - val mock = mock { - on { builderMethod() } doThrow IllegalArgumentException() - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - } - - @Test - fun testOngoingStubbing_doThrowClass() { - /* Given */ - val mock = mock { - on { builderMethod() } doThrow IllegalArgumentException::class - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - } - - @Test - fun testOngoingStubbing_doThrowVarargs() { - /* Given */ - val mock = mock { - on { builderMethod() }.doThrow( - IllegalArgumentException(), - UnsupportedOperationException() - ) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: UnsupportedOperationException) { - } - } - - @Test - fun testOngoingStubbing_doThrowClassVarargs() { - /* Given */ - val mock = mock { - on { builderMethod() }.doThrow( - IllegalArgumentException::class, - UnsupportedOperationException::class - ) - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: IllegalArgumentException) { - } - - try { - /* When */ - mock.builderMethod() - fail("No exception thrown") - } catch (e: UnsupportedOperationException) { - } - } - - @Test - fun testOngoingStubbing_doAnswer_lambda() { - /* Given */ - val mock = mock { - on { stringResult() } doAnswer { "result" } - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testOngoingStubbing_doAnswer_instance() { - /* Given */ - val mock = mock { - on { stringResult() } doAnswer Answer { "result" } - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testOngoingStubbing_doAnswer_returnsSelf() { - /* Given */ - val mock = mock { - on { builderMethod() } doAnswer Mockito.RETURNS_SELF - } - - /* When */ - val result = mock.builderMethod() - - /* Then */ - expect(result).toBe(mock) - } - - @Test - fun testOngoingStubbing_doAnswer_withArgument() { - /* Given */ - val mock = mock { - on { stringResult(any()) } doAnswer { "${it.arguments[0]}-result" } - } - - /* When */ - val result = mock.stringResult("argument") - - /* Then */ - expect(result).toBe("argument-result") - } - - @Test - fun testMockStubbingAfterCreatingMock() { - val mock = mock() - - //create stub after creation of mock - mock.stub { - on { stringResult() } doReturn "result" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result") - } - - @Test - fun testOverrideDefaultStub() { - /* Given mock with stub */ - val mock = mock { - on { stringResult() } doReturn "result1" - } - - /* override stub */ - mock.stub { - on { stringResult() } doReturn "result2" - } - - /* When */ - val result = mock.stringResult() - - /* Then */ - expect(result).toBe("result2") - } - - - @Test - fun stubbingTwiceWithArgumentMatchers() { - /* When */ - val mock = mock { - on { stringResult(argThat { this == "A" }) } doReturn "A" - on { stringResult(argThat { this == "B" }) } doReturn "B" - } - - /* Then */ - expect(mock.stringResult("A")).toBe("A") - expect(mock.stringResult("B")).toBe("B") - } - - @Test - fun stubbingTwiceWithCheckArgumentMatchers_throwsException() { - /* Expect */ - expectErrorWithMessage("null").on { - mock { - on { stringResult(check { }) } doReturn "A" - on { stringResult(check { }) } doReturn "B" - } - } - } - - @Test - fun doReturn_withSingleItemList() { - /* Given */ - val mock = mock { - on { stringResult() } doReturn listOf("a", "b") - } - - /* Then */ - expect(mock.stringResult()).toBe("a") - expect(mock.stringResult()).toBe("b") - } - - @Test - fun doReturn_throwsNPE() { - expectErrorWithMessage("look at the stack trace below") on { - - /* When */ - mock { - on { throwsNPE() } doReturn "result" - } - } - } - - @Test - fun doReturn_withGenericIntReturnType_on() { - /* Expect */ - expectErrorWithMessage("onGeneric") on { - - /* When */ - mock> { - on { genericMethod() } doReturn 2 - } - } - } - - @Test - fun doReturn_withGenericIntReturnType_onGeneric() { - /* Given */ - val mock = mock> { - onGeneric { genericMethod() } doReturn 2 - } - - /* Then */ - expect(mock.genericMethod()).toBe(2) - } - - @Test - fun doReturn_withGenericNullableReturnType_onGeneric() { - val m = mock> { - onGeneric { nullableReturnType() } doReturn "Test" - } - - expect(m.nullableReturnType()).toBe("Test") - } - - @Test - fun stubbingExistingMock() { - /* Given */ - val mock = mock() - - /* When */ - stubbing(mock) { - on { stringResult() } doReturn "result" - } - - /* Then */ - expect(mock.stringResult()).toBe("result") - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/SpyTest.kt b/mockito-kotlin/src/test/kotlin/test/SpyTest.kt deleted file mode 100644 index a8cf14a..0000000 --- a/mockito-kotlin/src/test/kotlin/test/SpyTest.kt +++ /dev/null @@ -1,119 +0,0 @@ -package test/* - * The MIT License - * - * Copyright (c) 2016 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* -import org.junit.After -import org.junit.Test -import org.mockito.Mockito -import java.util.* - -class SpyTest : TestBase() { - - private val interfaceInstance: MyInterface = MyClass() - private val openClassInstance: MyClass = MyClass() - private val closedClassInstance: ClosedClass = ClosedClass() - - @After - override fun tearDown() { - super.tearDown() - Mockito.validateMockitoUsage() - } - - @Test - fun spyInterfaceInstance() { - /* When */ - val result = spy(interfaceInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun spyOpenClassInstance() { - /* When */ - val result = spy(openClassInstance) - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun doReturnWithSpy() { - val date = spy(Date()) - doReturn(123L).whenever(date).time - expect(date.time).toBe(123L) - } - - @Test - fun doNothingWithSpy() { - val date = spy(Date(0)) - doNothing().whenever(date).time = 5L - date.time = 5L - expect(date.time).toBe(0L) - } - - @Test(expected = IllegalArgumentException::class) - fun doThrowWithSpy() { - val date = spy(Date(0)) - doThrow(IllegalArgumentException()).whenever(date).time - date.time - } - - @Test - fun doCallRealMethodWithSpy() { - val date = spy(Date(0)) - doReturn(123L).whenever(date).time - doCallRealMethod().whenever(date).time - expect(date.time).toBe(0L) - } - - @Test - fun doReturnWithDefaultInstanceSpyStubbing() { - val timeVal = 12L - - val dateSpy = spy { - on { time } doReturn timeVal - } - - expect(dateSpy.time).toBe(timeVal) - } - - @Test - fun doReturnWithSpyStubbing() { - val timeVal = 15L - - val dateSpy = spy(Date(0)) { - on { time } doReturn timeVal - } - - expect(dateSpy.time).toBe(timeVal) - } - - private interface MyInterface - private open class MyClass : MyInterface - private class ClosedClass -} - diff --git a/mockito-kotlin/src/test/kotlin/test/StubberTest.kt b/mockito-kotlin/src/test/kotlin/test/StubberTest.kt deleted file mode 100644 index 0e7ce65..0000000 --- a/mockito-kotlin/src/test/kotlin/test/StubberTest.kt +++ /dev/null @@ -1,103 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockitokotlin2.* -import org.junit.Test - -class StubberTest : TestBase() { - - @Test - fun testDoAnswer() { - val mock = mock() - - doAnswer { "Test" } - .whenever(mock) - .stringResult() - - expect(mock.stringResult()).toBe("Test") - } - - @Test - fun testDoCallRealMethod() { - val mock = mock() - - doReturn("Test").whenever(mock).stringResult() - doCallRealMethod().whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("Default") - } - - @Test - fun testDoNothing() { - val spy = spy(Open()) - val array = intArrayOf(3) - - doNothing().whenever(spy).modifiesContents(array) - spy.modifiesContents(array) - - expect(array[0]).toBe(3) - } - - @Test - fun testDoReturnValue() { - val mock = mock() - - doReturn("test").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - } - - @Test - fun testDoReturnNullValue() { - val mock = mock() - - doReturn(null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnNullValues() { - val mock = mock() - - doReturn(null, null).whenever(mock).stringResult() - - expect(mock.stringResult()).toBeNull() - expect(mock.stringResult()).toBeNull() - } - - @Test - fun testDoReturnValues() { - val mock = mock() - - doReturn("test", "test2").whenever(mock).stringResult() - - expect(mock.stringResult()).toBe("test") - expect(mock.stringResult()).toBe("test2") - } - - @Test - fun testDoThrowClass() { - val mock = mock() - - doThrow(IllegalStateException::class).whenever(mock).go() - - try { - mock.go() - throw AssertionError("Call should have thrown.") - } catch (e: IllegalStateException) { - } - } - - @Test - fun testDoThrow() { - val mock = mock() - - doThrow(IllegalStateException("test")).whenever(mock).go() - - expectErrorWithMessage("test").on { - mock.go() - } - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/TestBase.kt b/mockito-kotlin/src/test/kotlin/test/TestBase.kt deleted file mode 100644 index 1383ca3..0000000 --- a/mockito-kotlin/src/test/kotlin/test/TestBase.kt +++ /dev/null @@ -1,18 +0,0 @@ -package test - -import com.nhaarman.mockitokotlin2.internal.mockMakerInlineEnabled -import org.junit.After -import org.junit.Before - -abstract class TestBase { - - @Before - open fun setup() { - mockMakerInlineEnabled = false - } - - @After - open fun tearDown() { - mockMakerInlineEnabled = null - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/VerificationTest.kt b/mockito-kotlin/src/test/kotlin/test/VerificationTest.kt deleted file mode 100644 index 5a3bf39..0000000 --- a/mockito-kotlin/src/test/kotlin/test/VerificationTest.kt +++ /dev/null @@ -1,89 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* -import org.junit.Test -import org.mockito.exceptions.base.MockitoAssertionError - -class VerificationTest : TestBase() { - - @Test - fun atLeastXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atLeast(2)).string(any()) - } - } - - @Test - fun testAtLeastOnce() { - mock().apply { - string("") - string("") - - verify(this, atLeastOnce()).string(any()) - } - } - - @Test - fun atMostXInvocations() { - mock().apply { - string("") - string("") - - verify(this, atMost(2)).string(any()) - } - } - - @Test - fun testCalls() { - mock().apply { - string("") - string("") - - inOrder(this).verify(this, calls(2)).string(any()) - } - } - - @Test - fun testInOrderWithLambda() { - /* Given */ - val a = mock<() -> Unit>() - val b = mock<() -> Unit>() - - /* When */ - b() - a() - - /* Then */ - inOrder(a, b) { - verify(b).invoke() - verify(a).invoke() - } - } - - @Test - fun testClearInvocations() { - val mock = mock().apply { - string("") - } - - clearInvocations(mock) - - verify(mock, never()).string(any()) - } - - @Test - fun testDescription() { - try { - mock().apply { - verify(this, description("Test")).string(any()) - } - throw AssertionError("Verify should throw Exception.") - } catch (e: MockitoAssertionError) { - expect(e.message).toContain("Test") - } - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt b/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt deleted file mode 100644 index 5807c8f..0000000 --- a/mockito-kotlin/src/test/kotlin/test/VerifyTest.kt +++ /dev/null @@ -1,58 +0,0 @@ -package test - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import org.junit.Test -import org.mockito.exceptions.verification.TooLittleActualInvocations -import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent - -class VerifyTest : TestBase() { - - @Test - fun verify0Calls() { - val iface = mock() - - verify(iface) { - 0 * { call(any()) } - } - } - - @Test - fun verifyNCalls() { - val iface = mock() - - iface.call(42) - iface.call(42) - - verify(iface) { - 2 * { call(42) } - } - } - - @Test(expected = TooLittleActualInvocations::class) - fun verifyFailsWithWrongCount() { - val iface = mock() - - iface.call(0) - - verify(iface) { - 2 * { call(0) } - } - } - - @Test(expected = ArgumentsAreDifferent::class) - fun verifyFailsWithWrongArg() { - val iface = mock() - - iface.call(3) - - verify(iface) { - 1 * { call(0) } - } - } - - interface TestInterface { - fun call(arg: Int) - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt b/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt deleted file mode 100644 index b214fcc..0000000 --- a/mockito-kotlin/src/test/kotlin/test/createinstance/NullCasterTest.kt +++ /dev/null @@ -1,31 +0,0 @@ -package test.createinstance - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.internal.createInstance -import org.junit.Test -import test.TestBase - - -class NullCasterTest : TestBase() { - - @Test - fun createInstance() { - /* When */ - val result = createInstance(String::class) - - /* Then */ - expect(result).toBeNull() - } - - @Test - fun kotlinAcceptsNullValue() { - /* Given */ - val s: String = createInstance(String::class) - - /* When */ - acceptNonNullableString(s) - } - - private fun acceptNonNullableString(@Suppress("UNUSED_PARAMETER") s: String) { - } -} diff --git a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt deleted file mode 100644 index e8591b3..0000000 --- a/mockito-kotlin/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016 Ian J. De Silva - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.internal.mockMakerInlineEnabled -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever -import org.junit.Assume.assumeTrue -import org.junit.Before -import org.junit.Test -import java.io.IOException -import java.math.BigInteger - -class UsingMockMakerInlineTest { - - class ClassToBeMocked { - - fun doSomething(@Suppress("UNUSED_PARAMETER") c: ClassToBeMocked) { - } - - fun doSomethingElse(value: BigInteger): BigInteger { - return value.plus(BigInteger.ONE) - } - } - - @Before - fun setup() { - mockMakerInlineEnabled = null - assumeTrue(mockMakerInlineEnabled()) - } - - @Test - fun mockClosedClass() { - /* When */ - val result = mock() - - /* Then */ - expect(result).toNotBeNull() - } - - @Test - fun anyClosedClass() { - /* Given */ - val mock = mock() - - /* When */ - mock.doSomething(mock) - - /* Then */ - verify(mock).doSomething(any()) - } - - @Test - fun mockClosedFunction_mockStubbing() { - /* Given */ - val mock = mock { - on { doSomethingElse(any()) } doReturn (BigInteger.ONE) - } - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - @Test - fun mockClosedFunction_whenever() { - /* Given */ - val mock = mock() - whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) - - /* When */ - val result = mock.doSomethingElse(BigInteger.TEN) - - /* Then */ - expect(result).toBe(BigInteger.ONE) - } - - /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ - @Test - fun anyThrowableWithSingleThrowableConstructor() { - mock().apply { - throwableClass(ThrowableClass(IOException())) - verify(this).throwableClass(any()) - } - } - - interface Methods { - - fun throwableClass(t: ThrowableClass) - } - - class ThrowableClass(cause: Throwable) : Throwable(cause) - -} diff --git a/ops/mockMakerInline.sh b/ops/mockMakerInline.sh new file mode 100755 index 0000000..441b07d --- /dev/null +++ b/ops/mockMakerInline.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -ev + +if [ ${MOCK_MAKER} = "mock-maker-inline" ]; then + mkdir -p tests/src/test/resources/mockito-extensions + cp ops/org.mockito.plugins.MockMaker tests/src/test/resources/mockito-extensions/ +fi + +exit 0; + diff --git a/ops/org.mockito.plugins.MockMaker b/ops/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/ops/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 4e54ed1..ad6c4a2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ include 'mockito-kotlin' +include 'tests' diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..a29d680 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,7 @@ +Mockito-Kotlin tests +==================== + +Tests should be placed in this module. +CI is set up to execute tests for all major versions of Kotlin, +whilst keeping the library version on the latest version. +This ensures the library is backwards compatible for all Kotlin versions. diff --git a/tests/build.gradle b/tests/build.gradle new file mode 100644 index 0000000..1faf442 --- /dev/null +++ b/tests/build.gradle @@ -0,0 +1,29 @@ +buildscript { + ext.kotlin_version = '1.2.20' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.7' + + repositories { + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' + +repositories { + mavenCentral() + jcenter() +} + +dependencies { + compile files("${rootProject.projectDir}/mockito-kotlin/build/libs/mockito-kotlin-${rootProject.ext.versionName}.jar") + + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "org.mockito:mockito-core:2.13.0" + + testCompile "junit:junit:4.12" + testCompile "com.nhaarman:expect.kt:1.0.0" +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt new file mode 100644 index 0000000..551cc6b --- /dev/null +++ b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt @@ -0,0 +1,120 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.* +import org.junit.Test +import java.util.* + +class ArgumentCaptorTest : TestBase() { + + @Test + fun argumentCaptor_withSingleValue() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + val captor = argumentCaptor() + verify(date).time = captor.capture() + expect(captor.lastValue).toBe(5L) + } + + @Test + fun argumentCaptor_withNullValue_usingNonNullable() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.nullableString(null) + + /* Then */ + val captor = argumentCaptor() + verify(m).nullableString(captor.capture()) + expect(captor.lastValue).toBeNull() + } + + @Test + fun argumentCaptor_withNullValue_usingNullable() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.nullableString(null) + + /* Then */ + val captor = nullableArgumentCaptor() + verify(m).nullableString(captor.capture()) + expect(captor.lastValue).toBeNull() + } + + @Test + fun argumentCaptor_multipleValues() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + date.time = 7L + + /* Then */ + val captor = argumentCaptor() + 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() + verify(m, times(2)).nullableString(captor.capture()) + expect(captor.allValues).toBe(listOf("test", null)) + } + + @Test + fun argumentCaptor_callProperties() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.int(1) + m.int(2) + m.int(3) + m.int(4) + m.int(5) + + /* Then */ + argumentCaptor().apply { + verify(m, times(5)).int(capture()) + + expect(firstValue).toBe(1) + expect(secondValue).toBe(2) + expect(thirdValue).toBe(3) + expect(lastValue).toBe(5) + } + } + + @Test(expected = IndexOutOfBoundsException::class) + fun argumentCaptor_callPropertyNotAvailable() { + /* Given */ + val m: Methods = mock() + + /* When */ + m.int(1) + + /* Then */ + argumentCaptor().apply { + verify(m).int(capture()) + + expect(secondValue).toBe(2) + } + } +} diff --git a/tests/src/test/kotlin/test/BDDMockitoTest.kt b/tests/src/test/kotlin/test/BDDMockitoTest.kt new file mode 100644 index 0000000..ded1462 --- /dev/null +++ b/tests/src/test/kotlin/test/BDDMockitoTest.kt @@ -0,0 +1,103 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.* +import org.junit.Test + +class BDDMockitoTest { + + @Test + fun given_willReturn_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()).willReturn("Test") + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun givenLambda_willReturn_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given { mock.stringResult() }.willReturn("Test") + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun given_willReturnLambda_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()).willReturn { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun givenLambda_willReturnLambda_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given { mock.stringResult() } willReturn { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun given_willAnswer_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()).willAnswer { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun given_willAnswerInfix_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()) willAnswer { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + + @Test(expected = IllegalStateException::class) + fun given_willThrowInfix_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()) willThrow { IllegalStateException() } + mock.stringResult() + } + + @Test + fun then() { + /* Given */ + val mock = mock() + whenever(mock.stringResult()).thenReturn("Test") + + /* When */ + mock.stringResult() + + /* Then */ + then(mock).should().stringResult() + } +} diff --git a/tests/src/test/kotlin/test/Classes.kt b/tests/src/test/kotlin/test/Classes.kt new file mode 100644 index 0000000..cfbb7ab --- /dev/null +++ b/tests/src/test/kotlin/test/Classes.kt @@ -0,0 +1,83 @@ +package test + +/* +* The MIT License +* +* Copyright (c) 2016 Niek Haarman +* Copyright (c) 2007 Mockito contributors +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +open class Open { + open fun go(vararg arg: Any?) { + } + + open fun modifiesContents(a: IntArray) { + for (i in 0..a.size - 1) { + a[i] = a[i] + 1 + } + } + + open fun stringResult() = "Default" + + fun throwsNPE(): Any = throw NullPointerException("Test") +} + +class Closed + +interface Methods { + + fun intArray(i: IntArray) + fun closed(c: Closed) + fun closedArray(a: Array) + fun closedNullableArray(a: Array) + fun closedCollection(c: Collection) + fun closedList(c: List) + fun closedStringMap(m: Map) + fun closedSet(s: Set) + fun string(s: String) + fun int(i: Int) + fun closedVararg(vararg c: Closed) + fun throwableClass(t: ThrowableClass) + fun nullableString(s: String?) + + fun stringResult(): String + fun stringResult(s: String): String + fun nullableStringResult(): String? + fun builderMethod(): Methods + + fun nonDefaultReturnType(): ExtraInterface +} + +interface ExtraInterface + +abstract class ThrowingConstructor { + + constructor() { + error("Error in constructor") + } +} + +interface GenericMethods { + fun genericMethod(): T + fun nullableReturnType(): T? +} + +class ThrowableClass(cause: Throwable) : Throwable(cause) diff --git a/tests/src/test/kotlin/test/EqTest.kt b/tests/src/test/kotlin/test/EqTest.kt new file mode 100644 index 0000000..fe993c6 --- /dev/null +++ b/tests/src/test/kotlin/test/EqTest.kt @@ -0,0 +1,101 @@ +package test + +/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.eq +import com.nhaarman.mockitokotlin2.mock +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito + +class EqTest : TestBase() { + + private val interfaceInstance: MyInterface = MyClass() + private val openClassInstance: MyClass = MyClass() + private val closedClassInstance: ClosedClass = ClosedClass() + + private lateinit var doAnswer: Open + + @Before + fun setup() { + /* Create a proper Mockito state */ + doAnswer = Mockito.doAnswer { }.`when`(mock()) + } + + @After + override fun tearDown() { + super.tearDown() + + /* Close `any` Mockito state */ + doAnswer.go(0) + } + + @Test + fun eqInterfaceInstance() { + /* When */ + val result = eq(interfaceInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun eqOpenClassInstance() { + /* When */ + val result = eq(openClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun eqClosedClassInstance() { + /* When */ + val result = eq(closedClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun nullArgument() { + /* Given */ + val s: String? = null + + /* When */ + val result = eq(s) + + /* Then */ + expect(result).toBeNull() + } + + private interface MyInterface + private open class MyClass : MyInterface + class ClosedClass +} + diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt new file mode 100644 index 0000000..312d7a0 --- /dev/null +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -0,0 +1,183 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockitokotlin2.* +import org.junit.Test +import java.io.IOException + +class MatchersTest : TestBase() { + + @Test + fun anyString() { + mock().apply { + string("") + verify(this).string(any()) + } + } + + @Test + fun anyClosedClass() { + mock().apply { + closed(Closed()) + verify(this).closed(any()) + } + } + + @Test + fun anyIntArray() { + mock().apply { + intArray(intArrayOf()) + verify(this).intArray(any()) + } + } + + @Test + fun anyClassArray() { + mock().apply { + closedArray(arrayOf(Closed())) + verify(this).closedArray(anyArray()) + } + } + + @Test + fun anyNullableClassArray() { + mock().apply { + closedNullableArray(arrayOf(Closed(), null)) + verify(this).closedNullableArray(anyArray()) + } + } + + @Test + fun anyStringVararg() { + mock().apply { + closedVararg(Closed(), Closed()) + verify(this).closedVararg(anyVararg()) + } + } + + @Test + fun anyNull_neverVerifiesAny() { + mock().apply { + nullableString(null) + verify(this, never()).nullableString(any()) + } + } + + @Test + fun anyNull_verifiesAnyOrNull() { + mock().apply { + nullableString(null) + verify(this).nullableString(anyOrNull()) + } + } + + /** 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 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 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)) + } + } +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/MockMaker.kt b/tests/src/test/kotlin/test/MockMaker.kt new file mode 100644 index 0000000..54f3d91 --- /dev/null +++ b/tests/src/test/kotlin/test/MockMaker.kt @@ -0,0 +1,10 @@ +package test + +import org.mockito.internal.configuration.plugins.Plugins +import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker + + +internal var mockMakerInlineEnabled: Boolean? = null +internal fun mockMakerInlineEnabled(): Boolean { + return mockMakerInlineEnabled ?: (Plugins.getMockMaker() is InlineByteBuddyMockMaker) +} diff --git a/tests/src/test/kotlin/test/MockingTest.kt b/tests/src/test/kotlin/test/MockingTest.kt new file mode 100644 index 0000000..0d5730b --- /dev/null +++ b/tests/src/test/kotlin/test/MockingTest.kt @@ -0,0 +1,325 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.expect.fail +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever +import org.junit.Test +import org.mockito.Mockito +import org.mockito.exceptions.verification.WantedButNotInvoked +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode.BASIC +import java.io.PrintStream +import java.io.Serializable +import java.util.* + +class MockingTest : TestBase() { + + private lateinit var propertyInterfaceVariable: MyInterface + private lateinit var propertyClassVariable: MyClass + + @Test + fun localInterfaceValue() { + /* When */ + val instance: MyInterface = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyInterfaceVariable() { + /* When */ + propertyInterfaceVariable = mock() + + /* Then */ + expect(propertyInterfaceVariable).toNotBeNull() + } + + @Test + fun localClassValue() { + /* When */ + val instance: MyClass = mock() + + /* Then */ + expect(instance).toNotBeNull() + } + + @Test + fun propertyClassVariable() { + /* When */ + propertyClassVariable = mock() + + /* Then */ + expect(propertyClassVariable).toNotBeNull() + } + + @Test + fun untypedVariable() { + /* When */ + val instance = mock() + + expect(instance).toNotBeNull() + } + + @Test + fun deepStubs() { + val cal: Calendar = mock(defaultAnswer = Mockito.RETURNS_DEEP_STUBS) + whenever(cal.time.time).thenReturn(123L) + expect(cal.time.time).toBe(123L) + } + + + @Test + fun testMockStubbing_lambda() { + /* Given */ + val mock = mock() { + on { stringResult() } doReturn "A" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testMockStubbing_normalOverridesLambda() { + /* Given */ + val mock = mock() { + on { stringResult() }.doReturn("A") + } + whenever(mock.stringResult()).thenReturn("B") + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("B") + } + + + + @Test + fun mock_withCustomDefaultAnswer_parameterName() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_SELF) + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun mock_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock( + extraInterfaces = arrayOf(ExtraInterface::class) + ) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_MOCKS) + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mock_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mock_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch (e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mock_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mock_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mock_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + + @Test + fun mockStubbing_withSettingsAPI_extraInterfaces() { + /* Given */ + val mock = mock(extraInterfaces = arrayOf(ExtraInterface::class)) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_name() { + /* Given */ + val mock = mock(name = "myName") {} + + /* When */ + expectErrorWithMessage("myName.stringResult()") on { + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_defaultAnswer() { + /* Given */ + val mock = mock(defaultAnswer = Mockito.RETURNS_MOCKS) {} + + /* When */ + val result = mock.nonDefaultReturnType() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun mockStubbing_withSettingsAPI_serializable() { + /* Given */ + val mock = mock(serializable = true) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_serializableMode() { + /* Given */ + val mock = mock(serializableMode = BASIC) {} + + /* Then */ + expect(mock).toBeInstanceOf() + } + + @Test + fun mockStubbing_withSettingsAPI_verboseLogging() { + /* Given */ + val out = mock() + System.setOut(out) + val mock = mock(verboseLogging = true) {} + + try { + /* When */ + verify(mock).stringResult() + fail("Expected an exception") + } catch (e: WantedButNotInvoked) { + /* Then */ + verify(out).println("methods.stringResult();") + } + } + + @Test + fun mockStubbing_withSettingsAPI_invocationListeners() { + /* Given */ + var bool = false + val mock = mock(invocationListeners = arrayOf(InvocationListener { bool = true })) {} + + /* When */ + mock.stringResult() + + /* Then */ + expect(bool).toHold() + } + + @Test + fun mockStubbing_withSettingsAPI_stubOnly() { + /* Given */ + val mock = mock(stubOnly = true) {} + + /* Expect */ + expectErrorWithMessage("is a stubOnly() mock") on { + + /* When */ + verify(mock).stringResult() + } + } + + @Test + fun mockStubbing_withSettingsAPI_useConstructor() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = true) {} + } + } + + private interface MyInterface + private open class MyClass +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/OngoingStubbingTest.kt b/tests/src/test/kotlin/test/OngoingStubbingTest.kt new file mode 100644 index 0000000..aadcf07 --- /dev/null +++ b/tests/src/test/kotlin/test/OngoingStubbingTest.kt @@ -0,0 +1,322 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.expect.fail +import com.nhaarman.mockitokotlin2.* +import org.junit.Assume.assumeFalse +import org.junit.Test +import org.mockito.Mockito +import org.mockito.stubbing.Answer + +class OngoingStubbingTest : TestBase() { + + @Test + fun testOngoingStubbing_methodCall() { + /* Given */ + val mock = mock() + mock { + on(mock.stringResult()).doReturn("A") + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("A") + } + + @Test + fun testOngoingStubbing_builder() { + /* Given */ + val mock = mock { mock -> + on { builderMethod() } doReturn mock + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBeTheSameAs(mock) + } + + @Test + fun testOngoingStubbing_nullable() { + /* Given */ + val mock = mock { + on { nullableStringResult() } doReturn "Test" + } + + /* When */ + val result = mock.nullableStringResult() + + /* Then */ + expect(result).toBe("Test") + } + + @Test + fun testOngoingStubbing_doThrow() { + /* Given */ + val mock = mock { + on { builderMethod() } doThrow IllegalArgumentException() + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + } + + @Test + fun testOngoingStubbing_doThrowClass() { + /* Given */ + val mock = mock { + on { builderMethod() } doThrow IllegalArgumentException::class + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + } + + @Test + fun testOngoingStubbing_doThrowVarargs() { + /* Given */ + val mock = mock { + on { builderMethod() }.doThrow( + IllegalArgumentException(), + UnsupportedOperationException() + ) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: UnsupportedOperationException) { + } + } + + @Test + fun testOngoingStubbing_doThrowClassVarargs() { + /* Given */ + val mock = mock { + on { builderMethod() }.doThrow( + IllegalArgumentException::class, + UnsupportedOperationException::class + ) + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: IllegalArgumentException) { + } + + try { + /* When */ + mock.builderMethod() + fail("No exception thrown") + } catch (e: UnsupportedOperationException) { + } + } + + @Test + fun testOngoingStubbing_doAnswer_lambda() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOngoingStubbing_doAnswer_instance() { + /* Given */ + val mock = mock { + on { stringResult() } doAnswer Answer { "result" } + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOngoingStubbing_doAnswer_returnsSelf() { + /* Given */ + val mock = mock { + on { builderMethod() } doAnswer Mockito.RETURNS_SELF + } + + /* When */ + val result = mock.builderMethod() + + /* Then */ + expect(result).toBe(mock) + } + + @Test + fun testOngoingStubbing_doAnswer_withArgument() { + /* Given */ + val mock = mock { + on { stringResult(any()) } doAnswer { "${it.arguments[0]}-result" } + } + + /* When */ + val result = mock.stringResult("argument") + + /* Then */ + expect(result).toBe("argument-result") + } + + @Test + fun testMockStubbingAfterCreatingMock() { + val mock = mock() + + //create stub after creation of mock + mock.stub { + on { stringResult() } doReturn "result" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result") + } + + @Test + fun testOverrideDefaultStub() { + /* Given mock with stub */ + val mock = mock { + on { stringResult() } doReturn "result1" + } + + /* override stub */ + mock.stub { + on { stringResult() } doReturn "result2" + } + + /* When */ + val result = mock.stringResult() + + /* Then */ + expect(result).toBe("result2") + } + + + @Test + fun stubbingTwiceWithArgumentMatchers() { + /* When */ + val mock = mock { + on { stringResult(argThat { this == "A" }) } doReturn "A" + on { stringResult(argThat { this == "B" }) } doReturn "B" + } + + /* Then */ + expect(mock.stringResult("A")).toBe("A") + expect(mock.stringResult("B")).toBe("B") + } + + @Test + fun stubbingTwiceWithCheckArgumentMatchers_throwsException() { + /* Expect */ + expectErrorWithMessage("null").on { + mock { + on { stringResult(check { }) } doReturn "A" + on { stringResult(check { }) } doReturn "B" + } + } + } + + @Test + fun doReturn_withSingleItemList() { + /* Given */ + val mock = mock { + on { stringResult() } doReturn listOf("a", "b") + } + + /* Then */ + expect(mock.stringResult()).toBe("a") + expect(mock.stringResult()).toBe("b") + } + + @Test + fun doReturn_throwsNPE() { + assumeFalse(mockMakerInlineEnabled()) + expectErrorWithMessage("look at the stack trace below") on { + + /* When */ + mock { + on { throwsNPE() } doReturn "result" + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_on() { + /* Expect */ + expectErrorWithMessage("onGeneric") on { + + /* When */ + mock> { + on { genericMethod() } doReturn 2 + } + } + } + + @Test + fun doReturn_withGenericIntReturnType_onGeneric() { + /* Given */ + val mock = mock> { + onGeneric { genericMethod() } doReturn 2 + } + + /* Then */ + expect(mock.genericMethod()).toBe(2) + } + + @Test + fun doReturn_withGenericNullableReturnType_onGeneric() { + val m = mock> { + onGeneric { nullableReturnType() } doReturn "Test" + } + + expect(m.nullableReturnType()).toBe("Test") + } + + @Test + fun stubbingExistingMock() { + /* Given */ + val mock = mock() + + /* When */ + stubbing(mock) { + on { stringResult() } doReturn "result" + } + + /* Then */ + expect(mock.stringResult()).toBe("result") + } +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/SpyTest.kt b/tests/src/test/kotlin/test/SpyTest.kt new file mode 100644 index 0000000..a8cf14a --- /dev/null +++ b/tests/src/test/kotlin/test/SpyTest.kt @@ -0,0 +1,119 @@ +package test/* + * The MIT License + * + * Copyright (c) 2016 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.* +import org.junit.After +import org.junit.Test +import org.mockito.Mockito +import java.util.* + +class SpyTest : TestBase() { + + private val interfaceInstance: MyInterface = MyClass() + private val openClassInstance: MyClass = MyClass() + private val closedClassInstance: ClosedClass = ClosedClass() + + @After + override fun tearDown() { + super.tearDown() + Mockito.validateMockitoUsage() + } + + @Test + fun spyInterfaceInstance() { + /* When */ + val result = spy(interfaceInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun spyOpenClassInstance() { + /* When */ + val result = spy(openClassInstance) + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun doReturnWithSpy() { + val date = spy(Date()) + doReturn(123L).whenever(date).time + expect(date.time).toBe(123L) + } + + @Test + fun doNothingWithSpy() { + val date = spy(Date(0)) + doNothing().whenever(date).time = 5L + date.time = 5L + expect(date.time).toBe(0L) + } + + @Test(expected = IllegalArgumentException::class) + fun doThrowWithSpy() { + val date = spy(Date(0)) + doThrow(IllegalArgumentException()).whenever(date).time + date.time + } + + @Test + fun doCallRealMethodWithSpy() { + val date = spy(Date(0)) + doReturn(123L).whenever(date).time + doCallRealMethod().whenever(date).time + expect(date.time).toBe(0L) + } + + @Test + fun doReturnWithDefaultInstanceSpyStubbing() { + val timeVal = 12L + + val dateSpy = spy { + on { time } doReturn timeVal + } + + expect(dateSpy.time).toBe(timeVal) + } + + @Test + fun doReturnWithSpyStubbing() { + val timeVal = 15L + + val dateSpy = spy(Date(0)) { + on { time } doReturn timeVal + } + + expect(dateSpy.time).toBe(timeVal) + } + + private interface MyInterface + private open class MyClass : MyInterface + private class ClosedClass +} + diff --git a/tests/src/test/kotlin/test/StubberTest.kt b/tests/src/test/kotlin/test/StubberTest.kt new file mode 100644 index 0000000..0e7ce65 --- /dev/null +++ b/tests/src/test/kotlin/test/StubberTest.kt @@ -0,0 +1,103 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage +import com.nhaarman.mockitokotlin2.* +import org.junit.Test + +class StubberTest : TestBase() { + + @Test + fun testDoAnswer() { + val mock = mock() + + doAnswer { "Test" } + .whenever(mock) + .stringResult() + + expect(mock.stringResult()).toBe("Test") + } + + @Test + fun testDoCallRealMethod() { + val mock = mock() + + doReturn("Test").whenever(mock).stringResult() + doCallRealMethod().whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("Default") + } + + @Test + fun testDoNothing() { + val spy = spy(Open()) + val array = intArrayOf(3) + + doNothing().whenever(spy).modifiesContents(array) + spy.modifiesContents(array) + + expect(array[0]).toBe(3) + } + + @Test + fun testDoReturnValue() { + val mock = mock() + + doReturn("test").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + } + + @Test + fun testDoReturnNullValue() { + val mock = mock() + + doReturn(null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnNullValues() { + val mock = mock() + + doReturn(null, null).whenever(mock).stringResult() + + expect(mock.stringResult()).toBeNull() + expect(mock.stringResult()).toBeNull() + } + + @Test + fun testDoReturnValues() { + val mock = mock() + + doReturn("test", "test2").whenever(mock).stringResult() + + expect(mock.stringResult()).toBe("test") + expect(mock.stringResult()).toBe("test2") + } + + @Test + fun testDoThrowClass() { + val mock = mock() + + doThrow(IllegalStateException::class).whenever(mock).go() + + try { + mock.go() + throw AssertionError("Call should have thrown.") + } catch (e: IllegalStateException) { + } + } + + @Test + fun testDoThrow() { + val mock = mock() + + doThrow(IllegalStateException("test")).whenever(mock).go() + + expectErrorWithMessage("test").on { + mock.go() + } + } +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/TestBase.kt b/tests/src/test/kotlin/test/TestBase.kt new file mode 100644 index 0000000..95c76ec --- /dev/null +++ b/tests/src/test/kotlin/test/TestBase.kt @@ -0,0 +1,11 @@ +package test + +import org.junit.After + +abstract class TestBase { + + @After + open fun tearDown() { + mockMakerInlineEnabled = null + } +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/VerificationTest.kt b/tests/src/test/kotlin/test/VerificationTest.kt new file mode 100644 index 0000000..5a3bf39 --- /dev/null +++ b/tests/src/test/kotlin/test/VerificationTest.kt @@ -0,0 +1,89 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.* +import org.junit.Test +import org.mockito.exceptions.base.MockitoAssertionError + +class VerificationTest : TestBase() { + + @Test + fun atLeastXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atLeast(2)).string(any()) + } + } + + @Test + fun testAtLeastOnce() { + mock().apply { + string("") + string("") + + verify(this, atLeastOnce()).string(any()) + } + } + + @Test + fun atMostXInvocations() { + mock().apply { + string("") + string("") + + verify(this, atMost(2)).string(any()) + } + } + + @Test + fun testCalls() { + mock().apply { + string("") + string("") + + inOrder(this).verify(this, calls(2)).string(any()) + } + } + + @Test + fun testInOrderWithLambda() { + /* Given */ + val a = mock<() -> Unit>() + val b = mock<() -> Unit>() + + /* When */ + b() + a() + + /* Then */ + inOrder(a, b) { + verify(b).invoke() + verify(a).invoke() + } + } + + @Test + fun testClearInvocations() { + val mock = mock().apply { + string("") + } + + clearInvocations(mock) + + verify(mock, never()).string(any()) + } + + @Test + fun testDescription() { + try { + mock().apply { + verify(this, description("Test")).string(any()) + } + throw AssertionError("Verify should throw Exception.") + } catch (e: MockitoAssertionError) { + expect(e.message).toContain("Test") + } + } +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/VerifyTest.kt b/tests/src/test/kotlin/test/VerifyTest.kt new file mode 100644 index 0000000..5807c8f --- /dev/null +++ b/tests/src/test/kotlin/test/VerifyTest.kt @@ -0,0 +1,58 @@ +package test + +import com.nhaarman.mockitokotlin2.any +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import org.junit.Test +import org.mockito.exceptions.verification.TooLittleActualInvocations +import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent + +class VerifyTest : TestBase() { + + @Test + fun verify0Calls() { + val iface = mock() + + verify(iface) { + 0 * { call(any()) } + } + } + + @Test + fun verifyNCalls() { + val iface = mock() + + iface.call(42) + iface.call(42) + + verify(iface) { + 2 * { call(42) } + } + } + + @Test(expected = TooLittleActualInvocations::class) + fun verifyFailsWithWrongCount() { + val iface = mock() + + iface.call(0) + + verify(iface) { + 2 * { call(0) } + } + } + + @Test(expected = ArgumentsAreDifferent::class) + fun verifyFailsWithWrongArg() { + val iface = mock() + + iface.call(3) + + verify(iface) { + 1 * { call(0) } + } + } + + interface TestInterface { + fun call(arg: Int) + } +} \ No newline at end of file diff --git a/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt b/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt new file mode 100644 index 0000000..b214fcc --- /dev/null +++ b/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt @@ -0,0 +1,31 @@ +package test.createinstance + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.internal.createInstance +import org.junit.Test +import test.TestBase + + +class NullCasterTest : TestBase() { + + @Test + fun createInstance() { + /* When */ + val result = createInstance(String::class) + + /* Then */ + expect(result).toBeNull() + } + + @Test + fun kotlinAcceptsNullValue() { + /* Given */ + val s: String = createInstance(String::class) + + /* When */ + acceptNonNullableString(s) + } + + private fun acceptNonNullableString(@Suppress("UNUSED_PARAMETER") s: String) { + } +} diff --git a/tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt new file mode 100644 index 0000000..6c69ccb --- /dev/null +++ b/tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt @@ -0,0 +1,116 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Ian J. De Silva + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.* +import org.junit.Assume.assumeTrue +import org.junit.Before +import org.junit.Test +import test.mockMakerInlineEnabled +import java.io.IOException +import java.math.BigInteger + +class UsingMockMakerInlineTest { + + class ClassToBeMocked { + + fun doSomething(@Suppress("UNUSED_PARAMETER") c: ClassToBeMocked) { + } + + fun doSomethingElse(value: BigInteger): BigInteger { + return value.plus(BigInteger.ONE) + } + } + + @Before + fun setup() { + mockMakerInlineEnabled = null + assumeTrue(mockMakerInlineEnabled()) + } + + @Test + fun mockClosedClass() { + /* When */ + val result = mock() + + /* Then */ + expect(result).toNotBeNull() + } + + @Test + fun anyClosedClass() { + /* Given */ + val mock = mock() + + /* When */ + mock.doSomething(mock) + + /* Then */ + verify(mock).doSomething(any()) + } + + @Test + fun mockClosedFunction_mockStubbing() { + /* Given */ + val mock = mock { + on { doSomethingElse(any()) } doReturn (BigInteger.ONE) + } + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + @Test + fun mockClosedFunction_whenever() { + /* Given */ + val mock = mock() + whenever(mock.doSomethingElse(any())).doReturn(BigInteger.ONE) + + /* When */ + val result = mock.doSomethingElse(BigInteger.TEN) + + /* Then */ + expect(result).toBe(BigInteger.ONE) + } + + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ + @Test + fun anyThrowableWithSingleThrowableConstructor() { + mock().apply { + throwableClass(ThrowableClass(IOException())) + verify(this).throwableClass(any()) + } + } + + interface Methods { + + fun throwableClass(t: ThrowableClass) + } + + class ThrowableClass(cause: Throwable) : Throwable(cause) + +} -- cgit v1.2.3 From 5fa30e172666ddab87054fdcfde1b1f8a64feef6 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 3 Dec 2017 21:34:34 +0100 Subject: Support coroutines --- .gitignore | 2 + mockito-kotlin/build.gradle | 17 +++ .../com/nhaarman/mockitokotlin2/KStubbing.kt | 9 +- .../com/nhaarman/mockitokotlin2/Verification.kt | 12 ++ .../src/test/kotlin/test/CoroutinesTest.kt | 158 +++++++++++++++++++++ settings.gradle | 2 +- 6 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt diff --git a/.gitignore b/.gitignore index 1f606eb..0a1daff 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ out/ .idea/uiDesigner.xml .idea/vcs.xml .idea/workspace.xml + +*.orig diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index e5d1d25..d195990 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -25,7 +25,17 @@ repositories { dependencies { compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' + compile "org.mockito:mockito-core:2.13.0" + + testCompile 'junit:junit:4.12' + testCompile 'com.nhaarman:expect.kt:1.0.0' + + testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + testCompile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' + + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.21" } dokka { @@ -39,3 +49,10 @@ dokka { } } javadoc.dependsOn dokka + + +kotlin { + experimental { + coroutines "enable" + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt index 4ed5bf5..14e68e1 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt @@ -26,6 +26,7 @@ package com.nhaarman.mockitokotlin2 import com.nhaarman.mockitokotlin2.internal.createInstance +import kotlinx.coroutines.experimental.runBlocking import org.mockito.Mockito import org.mockito.stubbing.OngoingStubbing import kotlin.reflect.KClass @@ -42,7 +43,7 @@ inline fun T.stub(stubbing: KStubbing.(T) -> Unit): T { return apply { KStubbing(this).stubbing(this) } } -class KStubbing(private val mock: T) { +class KStubbing(val mock: T) { fun on(methodCall: R): OngoingStubbing = Mockito.`when`(methodCall) @@ -74,4 +75,10 @@ class KStubbing(private val mock: T) { ) } } + + fun KStubbing.onBlocking( + m: suspend T.() -> R + ): OngoingStubbing { + return runBlocking { Mockito.`when`(mock.m()) } + } } \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt index 1db20a6..ae52c9a 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -26,6 +26,7 @@ package com.nhaarman.mockitokotlin2 import com.nhaarman.mockitokotlin2.internal.createInstance +import kotlinx.coroutines.experimental.runBlocking import org.mockito.InOrder import org.mockito.Mockito import org.mockito.verification.VerificationAfterDelay @@ -41,6 +42,17 @@ fun verify(mock: T): T { return Mockito.verify(mock)!! } +/** + * Verifies certain suspending behavior happened once. + * + * Warning: Only one method call can be verified in the function. + * Subsequent method calls are ignored! + */ +fun verifyBlocking(mock: T, f: suspend T.() -> Unit) { + val m = Mockito.verify(mock) + runBlocking { m.f() } +} + /** * Verifies certain behavior happened at least once / exact number of times / never. * diff --git a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt new file mode 100644 index 0000000..16118ee --- /dev/null +++ b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt @@ -0,0 +1,158 @@ +@file:Suppress("EXPERIMENTAL_FEATURE_WARNING") + +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.verifyBlocking +import kotlinx.coroutines.experimental.CommonPool +import kotlinx.coroutines.experimental.delay +import kotlinx.coroutines.experimental.runBlocking +import kotlinx.coroutines.experimental.withContext +import org.junit.Test + + +class CoroutinesTest { + + @Test + fun stubbingSuspending() { + /* Given */ + val m = mock { + onBlocking { suspending() } doReturn 42 + } + + /* When */ + val result = runBlocking { m.suspending() } + + /* Then */ + expect(result).toBe(42) + } + + @Test + fun stubbingSuspending_usingSuspendingFunction() { + /* Given */ + val m = mock { + onBlocking { suspending() } doReturn runBlocking { SomeClass().result(42) } + } + + /* When */ + val result = runBlocking { m.suspending() } + + /* Then */ + expect(result).toBe(42) + } + + @Test + fun stubbingSuspending_runBlocking() = runBlocking { + /* Given */ + val m = mock { + onBlocking { suspending() } doReturn 42 + } + + /* When */ + val result = m.suspending() + + /* Then */ + expect(result).toBe(42) + } + + @Test + fun stubbingNonSuspending() { + /* Given */ + val m = mock { + onBlocking { nonsuspending() } doReturn 42 + } + + /* When */ + val result = m.nonsuspending() + + /* Then */ + expect(result).toBe(42) + } + + @Test + fun stubbingNonSuspending_runBlocking() = runBlocking { + /* Given */ + val m = mock { + onBlocking { nonsuspending() } doReturn 42 + } + + /* When */ + val result = m.nonsuspending() + + /* Then */ + expect(result).toBe(42) + } + + @Test + fun delayingResult() { + /* Given */ + val m = SomeClass() + + /* When */ + val result = runBlocking { m.delaying() } + + /* Then */ + expect(result).toBe(42) + } + + @Test + fun delayingResult_runBlocking() = runBlocking { + /* Given */ + val m = SomeClass() + + /* When */ + val result = m.delaying() + + /* Then */ + expect(result).toBe(42) + } + + @Test + fun verifySuspendFunctionCalled() { + /* Given */ + val m = mock() + + /* When */ + runBlocking { m.suspending() } + + /* Then */ + runBlocking { verify(m).suspending() } + } + + @Test + fun verifySuspendFunctionCalled_runBlocking() = runBlocking { + val m = mock() + + m.suspending() + + verify(m).suspending() + } + + @Test + fun verifySuspendFunctionCalled_verifyBlocking() { + val m = mock() + + runBlocking { m.suspending() } + + verifyBlocking(m) { suspending() } + } +} + +interface SomeInterface { + + suspend fun suspending(): Int + fun nonsuspending(): Int +} + +class SomeClass { + + suspend fun result(r: Int) = withContext(CommonPool) { r } + + suspend fun delaying() = withContext(CommonPool) { + delay(100) + 42 + } +} diff --git a/settings.gradle b/settings.gradle index ad6c4a2..5086f47 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ include 'mockito-kotlin' -include 'tests' +include 'tests' \ No newline at end of file -- cgit v1.2.3 From 6f9e1a7cc3eca9c2d8a6c54a0e533b772951d5d8 Mon Sep 17 00:00:00 2001 From: Danny Preussler Date: Sat, 9 Dec 2017 22:19:20 +0100 Subject: better inOrder for single arguments --- .../kotlin/com/nhaarman/mockitokotlin2/Verification.kt | 17 +++++++++++++++++ tests/src/test/kotlin/test/VerificationTest.kt | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt index ae52c9a..1919165 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -199,6 +199,23 @@ fun inOrder( Mockito.inOrder(*mocks).evaluation() } +/** + * Allows [InOrder] verification for a single mocked instance: + * + * mock.inOrder { + * verify().foo() + * } + * + */ +inline fun T.inOrder(block: InOrderOnType.() -> Any) { + block.invoke(InOrderOnType(this)) +} + +class InOrderOnType(private val t: T) : InOrder by inOrder(t as Any) { + + fun verify(): T = verify(t) +} + /** * Allows checking if given method was the only one invoked. */ diff --git a/tests/src/test/kotlin/test/VerificationTest.kt b/tests/src/test/kotlin/test/VerificationTest.kt index 5a3bf39..c2253bc 100644 --- a/tests/src/test/kotlin/test/VerificationTest.kt +++ b/tests/src/test/kotlin/test/VerificationTest.kt @@ -64,6 +64,23 @@ class VerificationTest : TestBase() { } } + @Test + fun testInOrderWithReceiver() { + /* Given */ + val mock = mock() + + /* When */ + mock.string("") + mock.int(0) + + /* Then */ + mock.inOrder { + verify().string(any()) + verify().int(any()) + verifyNoMoreInteractions() + } + } + @Test fun testClearInvocations() { val mock = mock().apply { -- cgit v1.2.3 From fb3581b67f9bf5a18dbc1e5a6ebb995d4ccb3387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Drobni=C4=8D?= Date: Sat, 14 Apr 2018 07:37:47 +0200 Subject: Make inOrder inline --- .../src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt index 1919165..66d21ac 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -192,7 +192,7 @@ fun inOrder(vararg mocks: Any): InOrder { * * Alias for [Mockito.inOrder]. */ -fun inOrder( +inline fun inOrder( vararg mocks: Any, evaluation: InOrder.() -> Unit ) { -- cgit v1.2.3 From 6837f30a09a753dc56a7d7d35598502e463dc6c5 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 10 May 2018 11:32:40 +0200 Subject: Include tests for default arguments --- tests/src/test/kotlin/test/VerifyTest.kt | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/src/test/kotlin/test/VerifyTest.kt b/tests/src/test/kotlin/test/VerifyTest.kt index 5807c8f..85915f3 100644 --- a/tests/src/test/kotlin/test/VerifyTest.kt +++ b/tests/src/test/kotlin/test/VerifyTest.kt @@ -52,7 +52,45 @@ class VerifyTest : TestBase() { } } + @Test + fun verifyDefaultArgs_firstParameter() { + /* Given */ + val m = mock() + + /* When */ + m.defaultArgs(a = 2) + + /* Then */ + verify(m).defaultArgs(2) + } + + @Test + fun verifyDefaultArgs_secondParameter() { + /* Given */ + val m = mock() + + /* When */ + m.defaultArgs(b = 2) + + /* Then */ + verify(m).defaultArgs(b = 2) + } + + @Test + fun verifyDefaultArgs_verifyDefaultValue() { + /* Given */ + val m = mock() + + /* When */ + m.defaultArgs(b = 2) + + /* Then */ + verify(m).defaultArgs(a = 3, b = 2) + } + interface TestInterface { fun call(arg: Int) + + fun defaultArgs(a: Int = 3, b: Int = 42) } } \ No newline at end of file -- cgit v1.2.3 From 200b4c8d5baec7af6f7217ed042f82d7baef02dc Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 10 May 2018 12:00:31 +0200 Subject: Adhere to Mockito.argThat contract in check() --- .../kotlin/com/nhaarman/mockitokotlin2/Verification.kt | 10 ++++++++-- tests/src/test/kotlin/test/MatchersTest.kt | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt index 1919165..356e520 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -241,7 +241,13 @@ If you are trying to verify an argument to be null, use `isNull()`. If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. """.trimIndent() ) - predicate(arg) - true + + try { + predicate(arg) + true + } catch (e: Error) { + e.printStackTrace() + false + } } ?: createInstance(T::class) } diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt index 312d7a0..60bfd27 100644 --- a/tests/src/test/kotlin/test/MatchersTest.kt +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -129,6 +129,21 @@ class MatchersTest : TestBase() { } } + @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 { -- cgit v1.2.3 From 76cb7cba2b125265f8b463bb5d63f53cb758c3e9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 10 May 2018 11:32:40 +0200 Subject: Include tests for default arguments --- tests/src/test/kotlin/test/VerifyTest.kt | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/src/test/kotlin/test/VerifyTest.kt b/tests/src/test/kotlin/test/VerifyTest.kt index 5807c8f..85915f3 100644 --- a/tests/src/test/kotlin/test/VerifyTest.kt +++ b/tests/src/test/kotlin/test/VerifyTest.kt @@ -52,7 +52,45 @@ class VerifyTest : TestBase() { } } + @Test + fun verifyDefaultArgs_firstParameter() { + /* Given */ + val m = mock() + + /* When */ + m.defaultArgs(a = 2) + + /* Then */ + verify(m).defaultArgs(2) + } + + @Test + fun verifyDefaultArgs_secondParameter() { + /* Given */ + val m = mock() + + /* When */ + m.defaultArgs(b = 2) + + /* Then */ + verify(m).defaultArgs(b = 2) + } + + @Test + fun verifyDefaultArgs_verifyDefaultValue() { + /* Given */ + val m = mock() + + /* When */ + m.defaultArgs(b = 2) + + /* Then */ + verify(m).defaultArgs(a = 3, b = 2) + } + interface TestInterface { fun call(arg: Int) + + fun defaultArgs(a: Int = 3, b: Int = 42) } } \ No newline at end of file -- cgit v1.2.3 From d247f0788187d98910f56f728cb4196c615b0119 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 10 May 2018 12:09:43 +0200 Subject: Include test case for calling suspend functions in inOrder --- mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt index 16118ee..8f59303 100644 --- a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt @@ -3,10 +3,7 @@ package test import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.verifyBlocking +import com.nhaarman.mockitokotlin2.* import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.runBlocking @@ -139,6 +136,17 @@ class CoroutinesTest { verifyBlocking(m) { suspending() } } + + @Test + fun verifySuspendMethod() = runBlocking { + val testSubject : SomeInterface = mock() + + testSubject.suspending() + + inOrder(testSubject) { + verify(testSubject).suspending() + } + } } interface SomeInterface { -- cgit v1.2.3 From a12e11f9c880d83e1e0626de01f842a7ccc8be1c Mon Sep 17 00:00:00 2001 From: igor Date: Sun, 18 Feb 2018 18:48:17 +0000 Subject: Added argument captor overloads --- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 14 +++++++++ tests/src/test/kotlin/test/ArgumentCaptorTest.kt | 33 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt index bc26bf5..9542446 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt @@ -36,6 +36,13 @@ inline fun argumentCaptor(): KArgumentCaptor { return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) } +/** + * Creates a [KArgumentCaptor] for given type, taking in a lambda to allow fast verification. + */ +inline fun argumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor { + return argumentCaptor().apply(f) +} + /** * Creates a [KArgumentCaptor] for given nullable type. */ @@ -43,6 +50,13 @@ inline fun nullableArgumentCaptor(): KArgumentCaptor { return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) } +/** + * Creates a [KArgumentCaptor] for given nullable type, taking in a lambda to allow fast verification. + */ +inline fun nullableArgumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor { + return nullableArgumentCaptor().apply(f) +} + /** * Alias for [ArgumentCaptor.capture]. */ diff --git a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt index 551cc6b..b79227b 100644 --- a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt +++ b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt @@ -1,6 +1,7 @@ package test import com.nhaarman.expect.expect +import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.mockitokotlin2.* import org.junit.Test import java.util.* @@ -117,4 +118,36 @@ class ArgumentCaptorTest : TestBase() { expect(secondValue).toBe(2) } } + + @Test + fun argumentCaptor_withSingleValue_lambda() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + argumentCaptor { + verify(date).time = capture() + expect(lastValue).toBe(5L) + } + } + + @Test + fun argumentCaptor_withSingleValue_lambda_properlyFails() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + expectErrorWithMessage("Expected: 3 but was: 5") on { + argumentCaptor { + verify(date).time = capture() + expect(lastValue).toBe(3L) + } + } + } } -- cgit v1.2.3 From 9d642a26188b545c1ef83615cea42d4bf2ee5985 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 13:30:05 +0200 Subject: Update Gradle dependency in README --- .idea/inspectionProfiles/Project_Default.xml | 6 ++++++ README.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..c33dd39 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index 5a424b4..99643f4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Mockito-Kotlin is available on Maven Central and JCenter. For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` with the latest version: ```groovy -testCompile "com.nhaarman:mockito-kotlin:x.x.x" +testCompile "com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x" ``` ## Example -- cgit v1.2.3 From 7dc287410c8ab0d58afc5cf7e18f03e27d55cd96 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 13:31:18 +0200 Subject: Test using Kotlin 1.2.50 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index eeeabb3..3d8ed77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,13 +9,13 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.20 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.50 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.2.20 + env: TERM=dumb KOTLIN_VERSION=1.2.50 env: -- cgit v1.2.3 From 7bd29c70888f7cf3ccfde3f60b3f0a4be200d40b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 13:31:52 +0200 Subject: Update Kotlin version to 1.2.50 --- mockito-kotlin/build.gradle | 2 +- tests/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index d195990..3648d61 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = "1.2.20" + ext.kotlin_version = "1.2.50" repositories { mavenCentral() diff --git a/tests/build.gradle b/tests/build.gradle index 1faf442..3d946d3 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.20' + ext.kotlin_version = '1.2.50' ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.7' repositories { -- cgit v1.2.3 From 524bc444dbbb912b64aa09db7fc7cc5ac6a781a2 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 13:32:20 +0200 Subject: Update Kotlin coroutines version to 0.23.3 --- mockito-kotlin/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 3648d61..86b6aaf 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -25,7 +25,7 @@ repositories { dependencies { compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' + compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.3' compile "org.mockito:mockito-core:2.13.0" @@ -33,9 +33,9 @@ dependencies { testCompile 'com.nhaarman:expect.kt:1.0.0' testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - testCompile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' + testCompile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.3' - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.21" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.23.3" } dokka { -- cgit v1.2.3 From a29303c8a59860b4dab88b4a76f55839d9e8bc86 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 13:32:46 +0200 Subject: Update Mockito to 2.19.0 --- mockito-kotlin/build.gradle | 2 +- tests/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 86b6aaf..b07e894 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -27,7 +27,7 @@ dependencies { compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.3' - compile "org.mockito:mockito-core:2.13.0" + compile "org.mockito:mockito-core:2.19.0" testCompile 'junit:junit:4.12' testCompile 'com.nhaarman:expect.kt:1.0.0' diff --git a/tests/build.gradle b/tests/build.gradle index 3d946d3..3da55c1 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -22,7 +22,7 @@ dependencies { compile files("${rootProject.projectDir}/mockito-kotlin/build/libs/mockito-kotlin-${rootProject.ext.versionName}.jar") compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compile "org.mockito:mockito-core:2.13.0" + compile "org.mockito:mockito-core:2.19.0" testCompile "junit:junit:4.12" testCompile "com.nhaarman:expect.kt:1.0.0" -- cgit v1.2.3 From fe18cc645a1b8b8f09ef54f0989b2da3fa3ed1b8 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 14:32:47 +0200 Subject: Include test to show how to mock a spy invocation with any() --- tests/src/test/kotlin/test/SpyTest.kt | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/tests/src/test/kotlin/test/SpyTest.kt b/tests/src/test/kotlin/test/SpyTest.kt index a8cf14a..c2f2bca 100644 --- a/tests/src/test/kotlin/test/SpyTest.kt +++ b/tests/src/test/kotlin/test/SpyTest.kt @@ -1,4 +1,6 @@ -package test/* +package test + +/* * The MIT License * * Copyright (c) 2016 Niek Haarman @@ -93,7 +95,7 @@ class SpyTest : TestBase() { @Test fun doReturnWithDefaultInstanceSpyStubbing() { val timeVal = 12L - + val dateSpy = spy { on { time } doReturn timeVal } @@ -104,7 +106,7 @@ class SpyTest : TestBase() { @Test fun doReturnWithSpyStubbing() { val timeVal = 15L - + val dateSpy = spy(Date(0)) { on { time } doReturn timeVal } @@ -112,8 +114,28 @@ class SpyTest : TestBase() { expect(dateSpy.time).toBe(timeVal) } - private interface MyInterface - private open class MyClass : MyInterface + @Test + fun passAnyStringToSpy() { + /* Given */ + val my = spy(MyClass()) + + /* When */ + doReturn("mocked").whenever(my).foo(any()) + + /* Then */ + expect(my.foo("hello")).toBe("mocked") + } + + private interface MyInterface { + + fun foo(value: String): String + } + + private open class MyClass : MyInterface { + + override fun foo(value: String): String = value + } + private class ClosedClass } -- cgit v1.2.3 From efe2ab19af1ac05d4fc6aa1003e1d8bda63d9c2c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 14:20:21 +0200 Subject: Support mocking with constructor arguments --- .../kotlin/com/nhaarman/mockitokotlin2/Mocking.kt | 21 ++++++++++++--- tests/src/test/kotlin/test/Classes.kt | 16 ++++++++++++ tests/src/test/kotlin/test/MockingTest.kt | 30 +++++++++++++++++----- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt index 8300ec9..afc0773 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt @@ -59,7 +59,7 @@ inline fun mock( verboseLogging: Boolean = false, invocationListeners: Array? = null, stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, + @Incubating useConstructor: UseConstructor? = null, @Incubating outerInstance: Any? = null ): T { return Mockito.mock( @@ -105,7 +105,7 @@ inline fun mock( verboseLogging: Boolean = false, invocationListeners: Array? = null, stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, + @Incubating useConstructor: UseConstructor? = null, @Incubating outerInstance: Any? = null, stubbing: KStubbing.(T) -> Unit ): T { @@ -153,7 +153,7 @@ fun withSettings( verboseLogging: Boolean = false, invocationListeners: Array? = null, stubOnly: Boolean = false, - @Incubating useConstructor: Boolean = false, + @Incubating useConstructor: UseConstructor? = null, @Incubating outerInstance: Any? = null ): MockSettings = Mockito.withSettings().apply { extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } @@ -165,10 +165,23 @@ fun withSettings( if (verboseLogging) verboseLogging() invocationListeners?.let { invocationListeners(*it) } if (stubOnly) stubOnly() - if (useConstructor) useConstructor() + useConstructor?.let { useConstructor(*it.args) } outerInstance?.let { outerInstance(it) } } +class UseConstructor private constructor(val args: Array) { + + companion object { + + /** Invokes the parameterless constructor. */ + fun parameterless() = UseConstructor(emptyArray()) + + /** Invokes a constructor with given arguments. */ + fun withArguments(vararg arguments: Any): UseConstructor { + return UseConstructor(arguments.asList().toTypedArray()) + } + } +} @Deprecated( "Use mock() with optional arguments instead.", diff --git a/tests/src/test/kotlin/test/Classes.kt b/tests/src/test/kotlin/test/Classes.kt index cfbb7ab..1792b64 100644 --- a/tests/src/test/kotlin/test/Classes.kt +++ b/tests/src/test/kotlin/test/Classes.kt @@ -75,6 +75,22 @@ abstract class ThrowingConstructor { } } +abstract class ThrowingConstructorWithArgument { + + constructor(s: String) { + error("Error in constructor: $s") + } +} + +abstract class NonThrowingConstructorWithArgument { + + constructor() { + error("Error in constructor") + } + + constructor(s: String) +} + interface GenericMethods { fun genericMethod(): T fun nullableReturnType(): T? diff --git a/tests/src/test/kotlin/test/MockingTest.kt b/tests/src/test/kotlin/test/MockingTest.kt index 0d5730b..5a45d1e 100644 --- a/tests/src/test/kotlin/test/MockingTest.kt +++ b/tests/src/test/kotlin/test/MockingTest.kt @@ -3,10 +3,10 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import com.nhaarman.mockitokotlin2.* +import com.nhaarman.mockitokotlin2.UseConstructor.Companion +import com.nhaarman.mockitokotlin2.UseConstructor.Companion.parameterless +import com.nhaarman.mockitokotlin2.UseConstructor.Companion.withArguments import org.junit.Test import org.mockito.Mockito import org.mockito.exceptions.verification.WantedButNotInvoked @@ -103,7 +103,6 @@ class MockingTest : TestBase() { } - @Test fun mock_withCustomDefaultAnswer_parameterName() { /* Given */ @@ -215,10 +214,27 @@ class MockingTest : TestBase() { fun mock_withSettingsAPI_useConstructor() { /* Given */ expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} + mock(useConstructor = parameterless()) {} + } + } + + @Test + fun mock_withSettingsAPI_useConstructorWithArguments_failing() { + /* Given */ + expectErrorWithMessage("Unable to create mock instance of type ") on { + mock(useConstructor = withArguments("Test")) {} } } + @Test + fun mock_withSettingsAPI_useConstructorWithArguments() { + /* When */ + val result = mock(useConstructor = withArguments("Test")) {} + + /* Then */ + expect(result).toNotBeNull() + } + @Test fun mockStubbing_withSettingsAPI_extraInterfaces() { /* Given */ @@ -316,7 +332,7 @@ class MockingTest : TestBase() { fun mockStubbing_withSettingsAPI_useConstructor() { /* Given */ expectErrorWithMessage("Unable to create mock instance of type ") on { - mock(useConstructor = true) {} + mock(useConstructor = parameterless()) {} } } -- cgit v1.2.3 From 87059d8f1c9bbce6564fc215174fdf89b1099ec9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Thu, 21 Jun 2018 15:06:28 +0200 Subject: Update README to show 2.x artifact badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99643f4..4361093 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Mockito-Kotlin -[ ![Download](https://maven-badges.herokuapp.com/maven-central/com.nhaarman/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/com.nhaarman/mockito-kotlin) +[ ![Download](https://maven-badges.herokuapp.com/maven-central/com.nhaarman.mockitokotlin2/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/com.nhaarman.mockitokotlin2/mockito-kotlin) A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. -- cgit v1.2.3 From 081d2cb856b590f6699ab1010c153aff89ceed82 Mon Sep 17 00:00:00 2001 From: Jon Travis Date: Wed, 22 Aug 2018 14:31:08 -0700 Subject: Inline `whenever` to let Mockito's UnfinishedStubbing messages work When Mockito detects unfinished stubbing, it will spit out an error containing: ``` Unfinished stubbing detected here: -> at com.nhaarman.mockitokotlin2.OngoingStubbingKt.whenever(OngoingStubbing.kt:42) ``` This is not useful in helping users track down unfinished stubbing. Instead, we inline `whenever` to make it read as: ``` Unfinished stubbing detected here: -> at com.me.MyTest.testMyThing(MyTest.kt:785) ``` --- .../com/nhaarman/mockitokotlin2/OngoingStubbing.kt | 3 ++- tests/src/test/kotlin/test/OngoingStubbingTest.kt | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt index 9f28d6b..5ccf9ae 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt @@ -37,7 +37,8 @@ import kotlin.reflect.KClass * * Alias for [Mockito.when]. */ -fun whenever(methodCall: T): OngoingStubbing { +@Suppress("NOTHING_TO_INLINE") +inline fun whenever(methodCall: T): OngoingStubbing { return Mockito.`when`(methodCall)!! } diff --git a/tests/src/test/kotlin/test/OngoingStubbingTest.kt b/tests/src/test/kotlin/test/OngoingStubbingTest.kt index aadcf07..513d6d7 100644 --- a/tests/src/test/kotlin/test/OngoingStubbingTest.kt +++ b/tests/src/test/kotlin/test/OngoingStubbingTest.kt @@ -7,6 +7,7 @@ import com.nhaarman.mockitokotlin2.* import org.junit.Assume.assumeFalse import org.junit.Test import org.mockito.Mockito +import org.mockito.exceptions.misusing.UnfinishedStubbingException import org.mockito.stubbing.Answer class OngoingStubbingTest : TestBase() { @@ -319,4 +320,20 @@ class OngoingStubbingTest : TestBase() { /* Then */ expect(mock.stringResult()).toBe("result") } -} \ No newline at end of file + + @Test + fun testMockitoStackOnUnfinishedStubbing() { + /* Given */ + val mock = mock() + whenever(mock.stringResult()) + + /* When */ + try { + mock.stringResult() + } catch(e: UnfinishedStubbingException) { + /* Then */ + expect(e.message).toContain("Unfinished stubbing detected here:") + expect(e.message).toContain("-> at test.OngoingStubbingTest.testMockitoStackOnUnfinishedStubbing") + } + } +} -- cgit v1.2.3 From 59eb1999a5b1f1d452674e99db8be8f91ee41f4b Mon Sep 17 00:00:00 2001 From: "P.J.Meisch" Date: Sun, 26 Aug 2018 11:11:34 +0200 Subject: add argThat(ArgumentMatcher) function --- .../src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt index 31cf24d..cc21191 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt @@ -26,6 +26,7 @@ package com.nhaarman.mockitokotlin2 import com.nhaarman.mockitokotlin2.internal.createInstance +import org.mockito.ArgumentMatcher import org.mockito.Mockito /** Object argument that is equal to the given value. */ @@ -70,6 +71,16 @@ inline fun argThat(noinline predicate: T.() -> Boolean): T { ) } +/** + * Registers a custom ArgumentMatcher. The original Mockito function registers the matcher and returns null, + * here the required type is returned. + * + * @param matcher The ArgumentMatcher on [T] to be registered. + */ +inline fun argThat(matcher: ArgumentMatcher): T { + return Mockito.argThat(matcher) ?: createInstance() +} + /** * Alias for [argThat]. * -- cgit v1.2.3 From 1ba5701ef803644ae1f6da289737943f62945776 Mon Sep 17 00:00:00 2001 From: Martin Brandtner Date: Mon, 3 Sep 2018 17:11:37 +0200 Subject: Bump mockito to version 2.21.0 --- mockito-kotlin/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index b07e894..6392e67 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -27,7 +27,7 @@ dependencies { compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.3' - compile "org.mockito:mockito-core:2.19.0" + compile "org.mockito:mockito-core:2.21.0" testCompile 'junit:junit:4.12' testCompile 'com.nhaarman:expect.kt:1.0.0' @@ -55,4 +55,4 @@ kotlin { experimental { coroutines "enable" } -} \ No newline at end of file +} -- cgit v1.2.3 From 0152304473ee3aadb6cfa633f5a6dd135393e1bc Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 25 Aug 2018 12:43:35 +0200 Subject: Replace OngoingStubbing.doReturn(List) with doReturnConsecutively. This fixes an conflicting overloads issue in the following case: ``` mock<() -> List> { on { invoke(any()) }.doReturn(emptyList()) } ``` Here `on` returns an `OngoingStubbing>`, and calling `doReturn(List)` can't choose between the single element parameter and the multi-item parameter. This is a breaking change, but can be simply fixed by the tools in IDEA. --- .../kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt | 13 +++++++++++++ tests/src/test/kotlin/test/Classes.kt | 1 + tests/src/test/kotlin/test/OngoingStubbingTest.kt | 4 ++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt index 5ccf9ae..fc685c4 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt @@ -29,6 +29,7 @@ import org.mockito.Mockito import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Answer import org.mockito.stubbing.OngoingStubbing +import kotlin.DeprecationLevel.ERROR import kotlin.reflect.KClass @@ -63,7 +64,19 @@ fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing { /** * Sets consecutive return values to be returned when the method is called. */ +@Deprecated( + "Use doReturnConsecutively instead", + ReplaceWith("doReturnConsecutively(ts)"), + level = ERROR +) inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing { + return doReturnConsecutively(ts) +} + +/** + * Sets consecutive return values to be returned when the method is called. + */ +inline infix fun OngoingStubbing.doReturnConsecutively(ts: List): OngoingStubbing { return thenReturn( ts[0], *ts.drop(1).toTypedArray() diff --git a/tests/src/test/kotlin/test/Classes.kt b/tests/src/test/kotlin/test/Classes.kt index 1792b64..c622008 100644 --- a/tests/src/test/kotlin/test/Classes.kt +++ b/tests/src/test/kotlin/test/Classes.kt @@ -88,6 +88,7 @@ abstract class NonThrowingConstructorWithArgument { error("Error in constructor") } + @Suppress("UNUSED_PARAMETER") constructor(s: String) } diff --git a/tests/src/test/kotlin/test/OngoingStubbingTest.kt b/tests/src/test/kotlin/test/OngoingStubbingTest.kt index 513d6d7..64ce9b3 100644 --- a/tests/src/test/kotlin/test/OngoingStubbingTest.kt +++ b/tests/src/test/kotlin/test/OngoingStubbingTest.kt @@ -255,7 +255,7 @@ class OngoingStubbingTest : TestBase() { fun doReturn_withSingleItemList() { /* Given */ val mock = mock { - on { stringResult() } doReturn listOf("a", "b") + on { stringResult() } doReturnConsecutively listOf("a", "b") } /* Then */ @@ -330,7 +330,7 @@ class OngoingStubbingTest : TestBase() { /* When */ try { mock.stringResult() - } catch(e: UnfinishedStubbingException) { + } catch (e: UnfinishedStubbingException) { /* Then */ expect(e.message).toContain("Unfinished stubbing detected here:") expect(e.message).toContain("-> at test.OngoingStubbingTest.testMockitoStackOnUnfinishedStubbing") -- cgit v1.2.3 From 4b61c238b761ea85f9d00adb14c9d82d3d5517dd Mon Sep 17 00:00:00 2001 From: Ryota Konno Date: Wed, 12 Sep 2018 23:35:29 +0900 Subject: Configuration 'compile' is obsolete and has been replaced 'implementation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4361093..871611e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Mockito-Kotlin is available on Maven Central and JCenter. For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` with the latest version: ```groovy -testCompile "com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x" +testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x" ``` ## Example -- cgit v1.2.3 From 4c9a1d117d743f55654155890342d5c0209cd0f2 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sat, 29 Sep 2018 23:47:14 +0200 Subject: Remove deprecated doReturn function --- .../kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt index fc685c4..5ec16be 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt @@ -61,18 +61,6 @@ fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing { return thenReturn(t, *ts) } -/** - * Sets consecutive return values to be returned when the method is called. - */ -@Deprecated( - "Use doReturnConsecutively instead", - ReplaceWith("doReturnConsecutively(ts)"), - level = ERROR -) -inline infix fun OngoingStubbing.doReturn(ts: List): OngoingStubbing { - return doReturnConsecutively(ts) -} - /** * Sets consecutive return values to be returned when the method is called. */ -- cgit v1.2.3 From 78e3ec18b17f786ffbca828ac763d7aa655685af Mon Sep 17 00:00:00 2001 From: "P.J.Meisch" Date: Sun, 30 Sep 2018 07:51:20 +0200 Subject: add tests for the argThat(matcher: ArgumentMatcher) function --- tests/src/test/kotlin/test/VarArgMatcherTest.kt | 68 +++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/src/test/kotlin/test/VarArgMatcherTest.kt diff --git a/tests/src/test/kotlin/test/VarArgMatcherTest.kt b/tests/src/test/kotlin/test/VarArgMatcherTest.kt new file mode 100644 index 0000000..847dfc1 --- /dev/null +++ b/tests/src/test/kotlin/test/VarArgMatcherTest.kt @@ -0,0 +1,68 @@ +package test + +import com.nhaarman.expect.expect +import com.nhaarman.mockitokotlin2.argThat +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.whenever +import org.junit.Test +import org.mockito.ArgumentMatcher +import org.mockito.internal.matchers.VarargMatcher +import org.mockito.invocation.InvocationOnMock +import org.mockito.stubbing.Answer + +/** + * + */ +class VarArgMatcherTest : TestBase() { + + @Test + fun testVarargAnySuccess() { + val t = mock() + + // a matcher to check if any of the varargs was equals to "b" + val matcher = VarargAnyMatcher({ "b" == it }, true, false) + + whenever(t.something(argThat(matcher))).thenAnswer(matcher) + + assert(t.something("a", "b", "c")) + } + + @Test + fun testVarargAnyFail() { + val t = mock() + + // a matcher to check if any of the varargs was equals to "d" + val matcher = VarargAnyMatcher({ "d" == it }, true, false) + + whenever(t.something(argThat(matcher))).thenAnswer(matcher) + + assert(!t.something("a", "b", "c")) + } + + /** + * a test class with a vararg function to test + */ + interface Tested { + fun something(vararg values: String): Boolean + } + + /** + * 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 success: R, + private val failure: R + ) : ArgumentMatcher, VarargMatcher, Answer { + private var anyMatched = false + + override fun matches(t: T): Boolean { + anyMatched = anyMatched or match(t) + return true + } + + override fun answer(i: InvocationOnMock) = if (anyMatched) success else failure + } + +} -- cgit v1.2.3 From 2a51e2fbfd8eedc54571713759799d13f3bba6ae Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 30 Sep 2018 09:40:32 +0200 Subject: Restructure tests --- tests/src/test/kotlin/test/Classes.kt | 1 + tests/src/test/kotlin/test/MatchersTest.kt | 51 +++++++++++++++++++ tests/src/test/kotlin/test/VarArgMatcherTest.kt | 68 ------------------------- 3 files changed, 52 insertions(+), 68 deletions(-) delete mode 100644 tests/src/test/kotlin/test/VarArgMatcherTest.kt diff --git a/tests/src/test/kotlin/test/Classes.kt b/tests/src/test/kotlin/test/Classes.kt index c622008..1572cbd 100644 --- a/tests/src/test/kotlin/test/Classes.kt +++ b/tests/src/test/kotlin/test/Classes.kt @@ -62,6 +62,7 @@ interface Methods { fun stringResult(s: String): String fun nullableStringResult(): String? fun builderMethod(): Methods + fun varargBooleanResult(vararg values: String): Boolean fun nonDefaultReturnType(): ExtraInterface } diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt index 60bfd27..8b3a87f 100644 --- a/tests/src/test/kotlin/test/MatchersTest.kt +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -4,6 +4,10 @@ import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.mockitokotlin2.* import org.junit.Test +import org.mockito.ArgumentMatcher +import org.mockito.internal.matchers.VarargMatcher +import org.mockito.invocation.InvocationOnMock +import org.mockito.stubbing.Answer import java.io.IOException class MatchersTest : TestBase() { @@ -195,4 +199,51 @@ class MatchersTest : TestBase() { 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 }, 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 }, true, false) + + /* When */ + whenever(t.varargBooleanResult(argThat(matcher))).thenAnswer(matcher) + + /* Then */ + expect(t.varargBooleanResult("a", "b", "c")).toBe(false) + } + + /** + * 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 success: R, + private val failure: R + ) : ArgumentMatcher, VarargMatcher, Answer { + private var anyMatched = false + + override fun matches(t: T): Boolean { + anyMatched = anyMatched or match(t) + return true + } + + override fun answer(i: InvocationOnMock) = if (anyMatched) success else failure + } } \ No newline at end of file diff --git a/tests/src/test/kotlin/test/VarArgMatcherTest.kt b/tests/src/test/kotlin/test/VarArgMatcherTest.kt deleted file mode 100644 index 847dfc1..0000000 --- a/tests/src/test/kotlin/test/VarArgMatcherTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package test - -import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.argThat -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.whenever -import org.junit.Test -import org.mockito.ArgumentMatcher -import org.mockito.internal.matchers.VarargMatcher -import org.mockito.invocation.InvocationOnMock -import org.mockito.stubbing.Answer - -/** - * - */ -class VarArgMatcherTest : TestBase() { - - @Test - fun testVarargAnySuccess() { - val t = mock() - - // a matcher to check if any of the varargs was equals to "b" - val matcher = VarargAnyMatcher({ "b" == it }, true, false) - - whenever(t.something(argThat(matcher))).thenAnswer(matcher) - - assert(t.something("a", "b", "c")) - } - - @Test - fun testVarargAnyFail() { - val t = mock() - - // a matcher to check if any of the varargs was equals to "d" - val matcher = VarargAnyMatcher({ "d" == it }, true, false) - - whenever(t.something(argThat(matcher))).thenAnswer(matcher) - - assert(!t.something("a", "b", "c")) - } - - /** - * a test class with a vararg function to test - */ - interface Tested { - fun something(vararg values: String): Boolean - } - - /** - * 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 success: R, - private val failure: R - ) : ArgumentMatcher, VarargMatcher, Answer { - private var anyMatched = false - - override fun matches(t: T): Boolean { - anyMatched = anyMatched or match(t) - return true - } - - override fun answer(i: InvocationOnMock) = if (anyMatched) success else failure - } - -} -- cgit v1.2.3 From 98584ecde2a31a7a242fbff11e342eac42d64a13 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 30 Sep 2018 09:26:53 +0200 Subject: [WIP] Experiment with Kotlin 1.3 and coroutines --- .travis.yml | 4 ++++ mockito-kotlin/build.gradle | 17 ++++++----------- .../kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt | 2 +- .../kotlin/com/nhaarman/mockitokotlin2/Verification.kt | 2 +- mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt | 14 +++++++------- tests/build.gradle | 4 +++- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d8ed77..0ee6174 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,12 +10,16 @@ matrix: env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.50 + - jdk: oraclejdk8 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.0-rc-116 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.1.61 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.2.50 + - jdk: oraclejdk8 + env: TERM=dumb KOTLIN_VERSION=1.3.0-rc-116 env: diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 6392e67..a9208e8 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,11 +3,12 @@ apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = "1.2.50" + ext.kotlin_version = "1.3.0-rc-116" repositories { mavenCentral() jcenter() + maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { @@ -21,11 +22,12 @@ buildscript { repositories { mavenCentral() jcenter() + maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.3' + compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0-eap13' compile "org.mockito:mockito-core:2.21.0" @@ -33,9 +35,9 @@ dependencies { testCompile 'com.nhaarman:expect.kt:1.0.0' testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - testCompile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.3' + testCompile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0-eap13' - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.23.3" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.30.0-eap13" } dokka { @@ -49,10 +51,3 @@ dokka { } } javadoc.dependsOn dokka - - -kotlin { - experimental { - coroutines "enable" - } -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt index 14e68e1..4844240 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt @@ -26,7 +26,7 @@ package com.nhaarman.mockitokotlin2 import com.nhaarman.mockitokotlin2.internal.createInstance -import kotlinx.coroutines.experimental.runBlocking +import kotlinx.coroutines.runBlocking import org.mockito.Mockito import org.mockito.stubbing.OngoingStubbing import kotlin.reflect.KClass diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt index 3453d37..bbc8625 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -26,7 +26,7 @@ package com.nhaarman.mockitokotlin2 import com.nhaarman.mockitokotlin2.internal.createInstance -import kotlinx.coroutines.experimental.runBlocking +import kotlinx.coroutines.runBlocking import org.mockito.InOrder import org.mockito.Mockito import org.mockito.verification.VerificationAfterDelay diff --git a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt index 8f59303..8f67904 100644 --- a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt @@ -4,10 +4,10 @@ package test import com.nhaarman.expect.expect import com.nhaarman.mockitokotlin2.* -import kotlinx.coroutines.experimental.CommonPool -import kotlinx.coroutines.experimental.delay -import kotlinx.coroutines.experimental.runBlocking -import kotlinx.coroutines.experimental.withContext +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext import org.junit.Test @@ -139,7 +139,7 @@ class CoroutinesTest { @Test fun verifySuspendMethod() = runBlocking { - val testSubject : SomeInterface = mock() + val testSubject: SomeInterface = mock() testSubject.suspending() @@ -157,9 +157,9 @@ interface SomeInterface { class SomeClass { - suspend fun result(r: Int) = withContext(CommonPool) { r } + suspend fun result(r: Int) = withContext(Dispatchers.Default) { r } - suspend fun delaying() = withContext(CommonPool) { + suspend fun delaying() = withContext(Dispatchers.Default) { delay(100) 42 } diff --git a/tests/build.gradle b/tests/build.gradle index 3da55c1..70c6c27 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,9 +1,10 @@ buildscript { - ext.kotlin_version = '1.2.50' ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.7' + ext.kotlin_version = '1.3.0-rc-116' repositories { mavenCentral() + maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" @@ -16,6 +17,7 @@ apply plugin: 'kotlin' repositories { mavenCentral() jcenter() + maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { -- cgit v1.2.3 From 12e390c2252b61acae2e00f939cc206938555f3c Mon Sep 17 00:00:00 2001 From: Jossi Wolf Date: Tue, 9 Oct 2018 13:34:44 +0200 Subject: Update to Kotlin 1.3-RC-146 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index a9208e8..ed4e2fd 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = "1.3.0-rc-116" + ext.kotlin_version = "1.3.0-rc-146 " repositories { mavenCentral() -- cgit v1.2.3 From dfd42570bc66c2412c249529d075bd3070ff7102 Mon Sep 17 00:00:00 2001 From: Jossi Wolf Date: Tue, 9 Oct 2018 13:35:51 +0200 Subject: Remove whitespace from Kotlin version --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index ed4e2fd..b58bba4 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = "1.3.0-rc-146 " + ext.kotlin_version = "1.3.0-rc-146" repositories { mavenCentral() -- cgit v1.2.3 From ae821f500d0a7238190caa710dbca2474565430a Mon Sep 17 00:00:00 2001 From: Jossi Wolf Date: Tue, 9 Oct 2018 13:36:29 +0200 Subject: Bump mockito-core to 2.23.0 to support stable coroutines --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index b58bba4..b3229fb 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -29,7 +29,7 @@ dependencies { compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0-eap13' - compile "org.mockito:mockito-core:2.21.0" + compile "org.mockito:mockito-core:2.23.0" testCompile 'junit:junit:4.12' testCompile 'com.nhaarman:expect.kt:1.0.0' -- cgit v1.2.3 From 5a303f67f56c1931fc851bcf2f73c9545a04887e Mon Sep 17 00:00:00 2001 From: Clint Checketts Date: Fri, 12 Oct 2018 22:03:26 -0600 Subject: Add argumentCaptor that create many at once for easy destructuring --- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 48 ++++++++++++++ tests/src/test/kotlin/test/ArgumentCaptorTest.kt | 76 ++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt index 9542446..426eb32 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt @@ -36,6 +36,54 @@ inline fun argumentCaptor(): KArgumentCaptor { return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) } +/** + * Creates 2 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor2(): Pair, KArgumentCaptor> { + return Pair(KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), + KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class)) +} + +/** + * Creates 3 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor3(): Triple, KArgumentCaptor, KArgumentCaptor> { + return Triple( + KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), + KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class), + KArgumentCaptor(ArgumentCaptor.forClass(C::class.java), C::class)) +} + +data class ArgumentCaptorHolder4( + val first: A, val second: B, val third: C, val fourth: D) +data class ArgumentCaptorHolder5( + val first: A, val second: B, val third: C, val fourth: D, val fifth: E) + + +/** + * Creates 4 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor4(): ArgumentCaptorHolder4, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { + return ArgumentCaptorHolder4( + KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), + KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class), + KArgumentCaptor(ArgumentCaptor.forClass(C::class.java), C::class), + KArgumentCaptor(ArgumentCaptor.forClass(D::class.java), D::class)) +} +/** + * Creates 4 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor5(): ArgumentCaptorHolder5, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { + return ArgumentCaptorHolder5( + KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), + KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class), + KArgumentCaptor(ArgumentCaptor.forClass(C::class.java), C::class), + KArgumentCaptor(ArgumentCaptor.forClass(D::class.java), D::class), + KArgumentCaptor(ArgumentCaptor.forClass(E::class.java), E::class)) +} + + + /** * Creates a [KArgumentCaptor] for given type, taking in a lambda to allow fast verification. */ diff --git a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt index b79227b..6f64f13 100644 --- a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt +++ b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt @@ -22,6 +22,82 @@ class ArgumentCaptorTest : TestBase() { expect(captor.lastValue).toBe(5L) } + @Test + fun argumentCaptor_destructuring2() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + val (captor1, captor2) = argumentCaptor2() + verify(date).time = captor1.capture() + verify(date).time = captor2.capture() + expect(captor1.lastValue).toBe(5L) + expect(captor2.lastValue).toBe(5L) + } + + @Test + fun argumentCaptor_destructuring3() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + val (captor1, captor2, captor3) = argumentCaptor3() + val verifyCaptor:KArgumentCaptor.() ->Unit = { + verify(date).time = capture() + expect(lastValue).toBe(5L) + } + captor1.apply(verifyCaptor) + captor2.apply(verifyCaptor) + captor3.apply(verifyCaptor) + } + + @Test + fun argumentCaptor_destructuring4() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + val (captor1, captor2, captor3, captor4) = argumentCaptor4() + val verifyCaptor:KArgumentCaptor.() ->Unit = { + verify(date).time = capture() + expect(lastValue).toBe(5L) + } + captor1.apply(verifyCaptor) + captor2.apply(verifyCaptor) + captor3.apply(verifyCaptor) + captor4.apply(verifyCaptor) + } + + @Test + fun argumentCaptor_destructuring5() { + /* Given */ + val date: Date = mock() + + /* When */ + date.time = 5L + + /* Then */ + val (captor1, captor2, captor3, captor4, captor5) = argumentCaptor5() + val verifyCaptor:KArgumentCaptor.() ->Unit = { + verify(date).time = capture() + expect(lastValue).toBe(5L) + } + captor1.apply(verifyCaptor) + captor2.apply(verifyCaptor) + captor3.apply(verifyCaptor) + captor4.apply(verifyCaptor) + captor5.apply(verifyCaptor) + } + @Test fun argumentCaptor_withNullValue_usingNonNullable() { /* Given */ -- cgit v1.2.3 From c248ee39543094b47c7bca85adfd948e34227b38 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:45:46 +0100 Subject: Update Kotlin to 1.3.0 --- .travis.yml | 4 ++-- mockito-kotlin/build.gradle | 10 ++++------ tests/build.gradle | 4 +--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0ee6174..66d5c6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.50 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.0-rc-116 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.0 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 @@ -19,7 +19,7 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.2.50 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.3.0-rc-116 + env: TERM=dumb KOTLIN_VERSION=1.3.0 env: diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index b3229fb..3f99bff 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,12 +3,11 @@ apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = "1.3.0-rc-146" + ext.kotlin_version = "1.3.0" repositories { mavenCentral() jcenter() - maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { @@ -22,12 +21,11 @@ buildscript { repositories { mavenCentral() jcenter() - maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0-eap13' + compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0' compile "org.mockito:mockito-core:2.23.0" @@ -35,9 +33,9 @@ dependencies { testCompile 'com.nhaarman:expect.kt:1.0.0' testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - testCompile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0-eap13' + testCompile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0' - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.30.0-eap13" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0" } dokka { diff --git a/tests/build.gradle b/tests/build.gradle index 70c6c27..54ec3fd 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,10 +1,9 @@ buildscript { ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.7' - ext.kotlin_version = '1.3.0-rc-116' + ext.kotlin_version = '1.3.0' repositories { mavenCentral() - maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" @@ -17,7 +16,6 @@ apply plugin: 'kotlin' repositories { mavenCentral() jcenter() - maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { -- cgit v1.2.3 From 585c7025b354e036ad0850bab618a7651f177e83 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:46:20 +0100 Subject: Update Mockito to 2.23.0 --- tests/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/build.gradle b/tests/build.gradle index 54ec3fd..f3eafda 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -22,7 +22,7 @@ dependencies { compile files("${rootProject.projectDir}/mockito-kotlin/build/libs/mockito-kotlin-${rootProject.ext.versionName}.jar") compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compile "org.mockito:mockito-core:2.19.0" + compile "org.mockito:mockito-core:2.23.0" testCompile "junit:junit:4.12" testCompile "com.nhaarman:expect.kt:1.0.0" -- cgit v1.2.3 From ef3ef93377d441a5f1c0248b83f486aa71e9551e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:46:51 +0100 Subject: Update Dokka gradle plugin to 0.9.17 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 3f99bff..7db1736 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -12,7 +12,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.15" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0" classpath "com.github.dcendents:android-maven-gradle-plugin:2.0" } -- cgit v1.2.3 From 4f596045992dfa2df0b7751014ee238b9b6770a3 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:47:04 +0100 Subject: Update Gradle bintray plugin to 1.8.4 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 7db1736..d10f7bc 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -13,7 +13,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17" - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0" + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4" classpath "com.github.dcendents:android-maven-gradle-plugin:2.0" } } -- cgit v1.2.3 From ab51bb3c1a80c0eea795a3bdd0ae737d0dab917e Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:48:06 +0100 Subject: Update Spring bintray plugin to 0.11.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6fd77d1..0bcf2eb 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { } } dependencies { - classpath "io.spring.gradle:spring-bintray-plugin:0.9.0" + classpath "io.spring.gradle:spring-bintray-plugin:0.11.1" } } -- cgit v1.2.3 From ab88f799f23be28be758abc9502581a8ca986f1c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:48:23 +0100 Subject: Update Gradle versions plugin to 0.20.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0bcf2eb..40ac3cd 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { } plugins { - id 'com.github.ben-manes.versions' version '0.17.0' + id 'com.github.ben-manes.versions' version '0.20.0' } apply from: 'gradle/scripts/tagging.gradle' -- cgit v1.2.3 From 52f879a6b9706039b1f9979b8f845183983543eb Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:49:17 +0100 Subject: Update Android maven plugin to 2.1 --- mockito-kotlin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index d10f7bc..03f0515 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -14,7 +14,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4" - classpath "com.github.dcendents:android-maven-gradle-plugin:2.0" + classpath "com.github.dcendents:android-maven-gradle-plugin:2.1" } } -- cgit v1.2.3 From c8bd94691c2825f79b7059905f986333a0c83288 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 29 Oct 2018 21:50:34 +0100 Subject: Update Gradle wrapper to 4.10.2 --- gradle/wrapper/gradle-wrapper.jar | Bin 54208 -> 54731 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 16f2083..6b6ea3a 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1ae18be..f2beea1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Dec 03 21:34:47 CET 2017 +#Mon Oct 29 21:53:52 CET 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/gradlew b/gradlew index 4453cce..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -155,7 +155,7 @@ if $cygwin ; then fi # Escape application args -save ( ) { +save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -- cgit v1.2.3 From a0648e296ca2b396ee359c101ae7f9f61b7cd0da Mon Sep 17 00:00:00 2001 From: Gabriel Casado Date: Sat, 15 Dec 2018 21:05:07 -0200 Subject: Add BDD will extension function --- .../main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt | 8 ++++++++ tests/src/test/kotlin/test/BDDMockitoTest.kt | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt index e2ca7ae..02f8c3c 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt @@ -27,6 +27,7 @@ package com.nhaarman.mockitokotlin2 import org.mockito.BDDMockito import org.mockito.BDDMockito.BDDMyOngoingStubbing +import org.mockito.stubbing.Answer /** * Alias for [BDDMockito.given]. @@ -49,6 +50,13 @@ fun then(mock: T): BDDMockito.Then { return BDDMockito.then(mock) } +/** + * Alias for [BDDMyOngoingStubbing.will] + * */ +infix fun BDDMyOngoingStubbing.will(value: Answer): BDDMockito.BDDMyOngoingStubbing { + return will(value) +} + /** * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a lambda. */ diff --git a/tests/src/test/kotlin/test/BDDMockitoTest.kt b/tests/src/test/kotlin/test/BDDMockitoTest.kt index ded1462..0d090b2 100644 --- a/tests/src/test/kotlin/test/BDDMockitoTest.kt +++ b/tests/src/test/kotlin/test/BDDMockitoTest.kt @@ -3,9 +3,22 @@ package test import com.nhaarman.expect.expect import com.nhaarman.mockitokotlin2.* import org.junit.Test +import org.mockito.stubbing.Answer class BDDMockitoTest { + @Test + fun given_will_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult()) will Answer { "Test" } + + /* Then */ + expect(mock.stringResult()).toBe("Test") + } + @Test fun given_willReturn_properlyStubs() { /* Given */ -- cgit v1.2.3 From a8072cb3a362819ed98323f23849865b7fcf883d Mon Sep 17 00:00:00 2001 From: Danny Preussler Date: Sun, 30 Dec 2018 14:14:46 +0100 Subject: #317 coroutines verify with verification mode --- .../main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt | 10 ++++++++++ mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt index bbc8625..b52e61e 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -53,6 +53,16 @@ fun verifyBlocking(mock: T, f: suspend T.() -> Unit) { runBlocking { m.f() } } +/** + * Verifies certain behavior happened at least once / exact number of times / never. + * + * Warning: Only one method call can be verified in the function. + * Subsequent method calls are ignored! + */ +fun verifyBlocking(mock: T, mode: VerificationMode, f: suspend T.() -> Unit) { + val m = Mockito.verify(mock, mode) + runBlocking { m.f() } +} /** * Verifies certain behavior happened at least once / exact number of times / never. * diff --git a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt index 8f67904..86d35b2 100644 --- a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt @@ -137,6 +137,16 @@ class CoroutinesTest { verifyBlocking(m) { suspending() } } + @Test + fun verifyAtLeastOnceSuspendFunctionCalled_verifyBlocking() { + val m = mock() + + runBlocking { m.suspending() } + runBlocking { m.suspending() } + + verifyBlocking(m, atLeastOnce()) { suspending() } + } + @Test fun verifySuspendMethod() = runBlocking { val testSubject: SomeInterface = mock() -- cgit v1.2.3 From a6bd76fafcbc4d05c6830a38abbedf205379bb6d Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Mon, 31 Dec 2018 12:35:43 +0100 Subject: Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0a1daff..bfee7ef 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ out/ .idea/caches/* .idea/compiler.xml +.idea/encodings.xml .idea/gradle.xml .idea/kotlinc.xml .idea/libraries/* -- cgit v1.2.3 From 294c8cc0396565e87e5046326ef45d086ca4c094 Mon Sep 17 00:00:00 2001 From: Sola Date: Sun, 26 Aug 2018 14:46:00 +0800 Subject: provide InvocationOnMock instance for BDDMyOngoingStubbing#willAnswer Signed-off-by: Sola --- .../main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt | 5 +++-- tests/src/test/kotlin/test/BDDMockitoTest.kt | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt index 02f8c3c..ead224d 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt @@ -27,6 +27,7 @@ package com.nhaarman.mockitokotlin2 import org.mockito.BDDMockito import org.mockito.BDDMockito.BDDMyOngoingStubbing +import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Answer /** @@ -60,8 +61,8 @@ infix fun BDDMyOngoingStubbing.will(value: Answer): BDDMockito.BDDMyOn /** * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a lambda. */ -infix fun BDDMyOngoingStubbing.willAnswer(value: () -> T): BDDMockito.BDDMyOngoingStubbing { - return willAnswer { value() } +infix fun BDDMyOngoingStubbing.willAnswer(value: (InvocationOnMock) -> T?): BDDMockito.BDDMyOngoingStubbing { + return willAnswer { value(it) } } /** diff --git a/tests/src/test/kotlin/test/BDDMockitoTest.kt b/tests/src/test/kotlin/test/BDDMockitoTest.kt index 0d090b2..3d43ac4 100644 --- a/tests/src/test/kotlin/test/BDDMockitoTest.kt +++ b/tests/src/test/kotlin/test/BDDMockitoTest.kt @@ -91,6 +91,21 @@ class BDDMockitoTest { expect(mock.stringResult()).toBe("Test") } + @Test + fun given_willAnswerInfix_withInvocationInfo_properlyStubs() { + /* Given */ + val mock = mock() + + /* When */ + given(mock.stringResult(any())) willAnswer { invocation -> + (invocation.arguments[0] as String) + .reversed() + } + + /* Then */ + expect(mock.stringResult("Test")).toBe("tseT") + } + @Test(expected = IllegalStateException::class) fun given_willThrowInfix_properlyStubs() { /* Given */ -- cgit v1.2.3 From ffaddbb4c733f4b04550c3adffa7e82645783abe Mon Sep 17 00:00:00 2001 From: pablisco Date: Wed, 27 Feb 2019 08:26:54 +0000 Subject: Add reified support for refEq like other matchers --- .../src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt index cc21191..1d89902 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt @@ -133,7 +133,7 @@ fun notNull(): T? { * Object argument that is reflection-equal to the given value with support for excluding * selected fields from a class. */ -fun refEq(value: T, vararg excludeFields: String): T? { - return Mockito.refEq(value, *excludeFields) +inline fun refEq(value: T, vararg excludeFields: String): T { + return Mockito.refEq(value, *excludeFields) ?: createInstance() } -- cgit v1.2.3 From fa6a72c30ff3e50749c376624c2ceeeb5ae740e9 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 19 Jun 2019 19:53:48 +0200 Subject: Include a test ensuring returns non-nullable type --- tests/src/test/kotlin/test/MatchersTest.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt index 8b3a87f..a17fe35 100644 --- a/tests/src/test/kotlin/test/MatchersTest.kt +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -228,6 +228,19 @@ class MatchersTest : TestBase() { 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) + + /* Then */ + verify(this).intArray(refEq(array)) + } + } + /** * 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. -- cgit v1.2.3 From f4405832a866e7f18cda90796b5c5e593cf68be1 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 19 Jun 2019 20:19:19 +0200 Subject: Include class parameters to avoid numbers in argumentCaptor signatures --- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 69 +++++++++++++++------- tests/src/test/kotlin/test/ArgumentCaptorTest.kt | 14 ++--- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt index 426eb32..ce06975 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt @@ -39,51 +39,76 @@ inline fun argumentCaptor(): KArgumentCaptor { /** * Creates 2 [KArgumentCaptor]s for given types. */ -inline fun argumentCaptor2(): Pair, KArgumentCaptor> { - return Pair(KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), - KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class)) +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class +): Pair, KArgumentCaptor> { + return Pair( + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b) + ) } /** * Creates 3 [KArgumentCaptor]s for given types. */ -inline fun argumentCaptor3(): Triple, KArgumentCaptor, KArgumentCaptor> { +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class, + c: KClass = C::class +): Triple, KArgumentCaptor, KArgumentCaptor> { return Triple( - KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), - KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class), - KArgumentCaptor(ArgumentCaptor.forClass(C::class.java), C::class)) + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), + KArgumentCaptor(ArgumentCaptor.forClass(c.java), c) + ) } data class ArgumentCaptorHolder4( - val first: A, val second: B, val third: C, val fourth: D) + val first: A, val second: B, val third: C, val fourth: D +) + data class ArgumentCaptorHolder5( - val first: A, val second: B, val third: C, val fourth: D, val fifth: E) + val first: A, val second: B, val third: C, val fourth: D, val fifth: E +) /** * Creates 4 [KArgumentCaptor]s for given types. */ -inline fun argumentCaptor4(): ArgumentCaptorHolder4, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class, + c: KClass = C::class, + d: KClass = D::class +): ArgumentCaptorHolder4, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { return ArgumentCaptorHolder4( - KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), - KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class), - KArgumentCaptor(ArgumentCaptor.forClass(C::class.java), C::class), - KArgumentCaptor(ArgumentCaptor.forClass(D::class.java), D::class)) + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), + KArgumentCaptor(ArgumentCaptor.forClass(c.java), c), + KArgumentCaptor(ArgumentCaptor.forClass(d.java), d) + ) } + /** * Creates 4 [KArgumentCaptor]s for given types. */ -inline fun argumentCaptor5(): ArgumentCaptorHolder5, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class, + c: KClass = C::class, + d: KClass = D::class, + e: KClass = E::class +): ArgumentCaptorHolder5, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { return ArgumentCaptorHolder5( - KArgumentCaptor(ArgumentCaptor.forClass(A::class.java), A::class), - KArgumentCaptor(ArgumentCaptor.forClass(B::class.java), B::class), - KArgumentCaptor(ArgumentCaptor.forClass(C::class.java), C::class), - KArgumentCaptor(ArgumentCaptor.forClass(D::class.java), D::class), - KArgumentCaptor(ArgumentCaptor.forClass(E::class.java), E::class)) + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), + KArgumentCaptor(ArgumentCaptor.forClass(c.java), c), + KArgumentCaptor(ArgumentCaptor.forClass(d.java), d), + KArgumentCaptor(ArgumentCaptor.forClass(e.java), e) + ) } - - /** * Creates a [KArgumentCaptor] for given type, taking in a lambda to allow fast verification. */ diff --git a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt index 6f64f13..10ddb5e 100644 --- a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt +++ b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt @@ -31,7 +31,7 @@ class ArgumentCaptorTest : TestBase() { date.time = 5L /* Then */ - val (captor1, captor2) = argumentCaptor2() + val (captor1, captor2) = argumentCaptor() verify(date).time = captor1.capture() verify(date).time = captor2.capture() expect(captor1.lastValue).toBe(5L) @@ -47,8 +47,8 @@ class ArgumentCaptorTest : TestBase() { date.time = 5L /* Then */ - val (captor1, captor2, captor3) = argumentCaptor3() - val verifyCaptor:KArgumentCaptor.() ->Unit = { + val (captor1, captor2, captor3) = argumentCaptor() + val verifyCaptor: KArgumentCaptor.() -> Unit = { verify(date).time = capture() expect(lastValue).toBe(5L) } @@ -66,8 +66,8 @@ class ArgumentCaptorTest : TestBase() { date.time = 5L /* Then */ - val (captor1, captor2, captor3, captor4) = argumentCaptor4() - val verifyCaptor:KArgumentCaptor.() ->Unit = { + val (captor1, captor2, captor3, captor4) = argumentCaptor() + val verifyCaptor: KArgumentCaptor.() -> Unit = { verify(date).time = capture() expect(lastValue).toBe(5L) } @@ -86,8 +86,8 @@ class ArgumentCaptorTest : TestBase() { date.time = 5L /* Then */ - val (captor1, captor2, captor3, captor4, captor5) = argumentCaptor5() - val verifyCaptor:KArgumentCaptor.() ->Unit = { + val (captor1, captor2, captor3, captor4, captor5) = argumentCaptor() + val verifyCaptor: KArgumentCaptor.() -> Unit = { verify(date).time = capture() expect(lastValue).toBe(5L) } -- cgit v1.2.3 From 9c90f0fde4fcda8e51c9d92874af49ea2b606837 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 19 Jun 2019 20:23:08 +0200 Subject: Manually provide component functions for captor holder classes This tightens the public API for these classes. --- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 32 ++++++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt index ce06975..be69337 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt @@ -64,13 +64,33 @@ inline fun argumentCaptor( ) } -data class ArgumentCaptorHolder4( - val first: A, val second: B, val third: C, val fourth: D -) +class ArgumentCaptorHolder4( + val first: A, + val second: B, + val third: C, + val fourth: D +) { + + operator fun component1() = first + operator fun component2() = second + operator fun component3() = third + operator fun component4() = fourth +} -data class ArgumentCaptorHolder5( - val first: A, val second: B, val third: C, val fourth: D, val fifth: E -) +class ArgumentCaptorHolder5( + val first: A, + val second: B, + val third: C, + val fourth: D, + val fifth: E +) { + + operator fun component1() = first + operator fun component2() = second + operator fun component3() = third + operator fun component4() = fourth + operator fun component5() = fifth +} /** -- cgit v1.2.3 From b850ab164452a852ec43eb7e720216439554d7a7 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Wed, 19 Jun 2019 20:42:53 +0200 Subject: Test against Kotlin 1.3.40 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 66d5c6c..192cdef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.50 - jdk: oraclejdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.0 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.40 - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: oraclejdk8 @@ -19,7 +19,7 @@ matrix: - jdk: oraclejdk8 env: TERM=dumb KOTLIN_VERSION=1.2.50 - jdk: oraclejdk8 - env: TERM=dumb KOTLIN_VERSION=1.3.0 + env: TERM=dumb KOTLIN_VERSION=1.3.40 env: -- cgit v1.2.3 From feaf63e2ea38828b25dd23bf34a8128aefe0d50b Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 5 Jul 2019 14:39:15 +0200 Subject: Make after() return type non-null --- .../src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt | 4 ++-- tests/src/test/kotlin/test/VerificationTest.kt | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt index b52e61e..b8e124c 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt @@ -165,8 +165,8 @@ fun description(description: String): VerificationMode { * interaction rather than failing immediately if has not already happened. May be useful for testing in concurrent * conditions. */ -fun after(millis: Long): VerificationAfterDelay? { - return Mockito.after(millis) +fun after(millis: Long): VerificationAfterDelay { + return Mockito.after(millis)!! } /** diff --git a/tests/src/test/kotlin/test/VerificationTest.kt b/tests/src/test/kotlin/test/VerificationTest.kt index c2253bc..1858dec 100644 --- a/tests/src/test/kotlin/test/VerificationTest.kt +++ b/tests/src/test/kotlin/test/VerificationTest.kt @@ -103,4 +103,12 @@ class VerificationTest : TestBase() { expect(e.message).toContain("Test") } } + + @Test + fun testAfter() { + mock().apply { + int(3) + verify(this, after(10)).int(3) + } + } } \ No newline at end of file -- cgit v1.2.3 From 145e0c1b8f2764540400fe75597a40a8941abf9c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 5 Jul 2019 15:27:49 +0200 Subject: Manually provide values for primitive types On the JVM, primitive types get unboxed automatically, leading to NPE's when the null quirk is used. --- .../mockitokotlin2/internal/CreateInstance.kt | 12 +++- tests/src/test/kotlin/test/Classes.kt | 7 +++ tests/src/test/kotlin/test/MatchersTest.kt | 71 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt index 6041238..4d9b5f5 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt @@ -29,7 +29,17 @@ import kotlin.reflect.KClass import java.lang.reflect.Array as JavaArray inline fun createInstance(): T { - return createInstance(T::class) + return when (T::class) { + Boolean::class -> false as T + Byte::class -> 0.toByte() as T + Char::class -> 0.toChar() as T + Short::class -> 0.toShort() as T + Int::class -> 0 as T + Long::class -> 0L as T + Float::class -> 0f as T + Double::class -> 0.0 as T + else -> createInstance(T::class) + } } fun createInstance(kClass: KClass): T { diff --git a/tests/src/test/kotlin/test/Classes.kt b/tests/src/test/kotlin/test/Classes.kt index 1572cbd..87b758d 100644 --- a/tests/src/test/kotlin/test/Classes.kt +++ b/tests/src/test/kotlin/test/Classes.kt @@ -53,7 +53,14 @@ interface Methods { fun closedStringMap(m: Map) fun closedSet(s: Set) fun string(s: String) + fun boolean(b: Boolean) + fun byte(b: Byte) + fun char(c: Char) + fun short(s: Short) fun int(i: Int) + fun long(l: Long) + fun float(f: Float) + fun double(d: Double) fun closedVararg(vararg c: Closed) fun throwableClass(t: ThrowableClass) fun nullableString(s: String?) diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt index a17fe35..fa053b4 100644 --- a/tests/src/test/kotlin/test/MatchersTest.kt +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -20,6 +20,14 @@ class MatchersTest : TestBase() { } } + @Test + fun anyInt() { + mock().apply { + string("") + verify(this).string(any()) + } + } + @Test fun anyClosedClass() { mock().apply { @@ -76,6 +84,69 @@ class MatchersTest : TestBase() { } } + @Test + fun anyNull_forPrimitiveBoolean() { + mock().apply { + boolean(false) + verify(this).boolean(anyOrNull()) + } + } + @Test + fun anyNull_forPrimitiveByte() { + mock().apply { + byte(3) + verify(this).byte(anyOrNull()) + } + } + + @Test + fun anyNull_forPrimitiveChar() { + mock().apply { + char('a') + verify(this).char(anyOrNull()) + } + } + + @Test + fun anyNull_forPrimitiveShort() { + mock().apply { + short(3) + verify(this).short(anyOrNull()) + } + } + + @Test + fun anyNull_forPrimitiveInt() { + mock().apply { + int(3) + verify(this).int(anyOrNull()) + } + } + + @Test + fun anyNull_forPrimitiveLong() { + mock().apply { + long(3) + verify(this).long(anyOrNull()) + } + } + + @Test + fun anyNull_forPrimitiveFloat() { + mock().apply { + float(3f) + verify(this).float(anyOrNull()) + } + } + + @Test + fun anyNull_forPrimitiveDouble() { + mock().apply { + double(3.0) + verify(this).double(anyOrNull()) + } + } + /** https://github.com/nhaarman/mockito-kotlin/issues/27 */ @Test fun anyThrowableWithSingleThrowableConstructor() { -- cgit v1.2.3 From 97d8c90e935bfb4ed11dffc71cb63cf9444be6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brais=20Gab=C3=ADn?= Date: Tue, 3 Sep 2019 19:33:29 +0200 Subject: Fix MatchersTest --- tests/src/test/kotlin/test/MatchersTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt index fa053b4..4aea90e 100644 --- a/tests/src/test/kotlin/test/MatchersTest.kt +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -23,8 +23,8 @@ class MatchersTest : TestBase() { @Test fun anyInt() { mock().apply { - string("") - verify(this).string(any()) + int(3) + verify(this).int(any()) } } -- cgit v1.2.3 From 3f471b4da098060db0295481674df012c5f11073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brais=20Gab=C3=ADn?= Date: Tue, 3 Sep 2019 19:52:02 +0200 Subject: Fix travisCI It seems that oraclejdk8 is not working with the new images of travis https://travis-ci.community/t/error-installing-oraclejdk8-expected-feature-release-number-in-range-of-9-to-14-but-got-8 --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 192cdef..9b4a49e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,21 +4,21 @@ language: java matrix: include: - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.61 - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.50 - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.40 - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb KOTLIN_VERSION=1.1.61 - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb KOTLIN_VERSION=1.2.50 - - jdk: oraclejdk8 + - jdk: openjdk8 env: TERM=dumb KOTLIN_VERSION=1.3.40 -- cgit v1.2.3 From 4bcf696553bc866508aeac5e1ebe28b810ac667d Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 8 Sep 2019 09:55:00 +0200 Subject: Update README to include build instructions --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index 871611e..d8087af 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,34 @@ fun doAction_doesSomething(){ ``` For more info and samples, see the [Wiki](https://github.com/nhaarman/mockito-kotlin/wiki). + +## Building + +Mockito-Kotlin is built with Gradle. + + - `./gradlew build` builds the project + - `./gradlew publishToMavenLocal` installs the maven artifacts in your local repository + - `./gradlew assemble && ./gradlew test` runs the test suite (See Testing below) + +### Versioning + +Mockito-Kotlin roughly follows SEMVER; version names are parsed from +git tags using `git describe`. + +### Testing + +Mockito-Kotlin's test suite is located in a separate `tests` module, +to allow running the tests using several Kotlin versions whilst still +keeping the base module at a recent version. + +Testing thus must be done in two stages: one to build the base artifact +to test against, and the actual execution of the tests against the +built artifact: + + - `./gradlew assemble` builds the base artifact + - `./gradlew test` runs the tests against the built artifact. + +Usually it is enough to test only using the default Kotlin versions; +CI will test against multiple versions. +If you want to test using a different Kotlin version locally, set +an environment variable `KOTLIN_VERSION` and run the tests. -- cgit v1.2.3 From 1e505f00d0f1034a36f736a6703d63d70bc3156c Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 8 Sep 2019 09:55:19 +0200 Subject: Actually test against multiple Kotlin versions --- tests/build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/build.gradle b/tests/build.gradle index f3eafda..8990624 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,6 +1,5 @@ buildscript { - ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.0.7' - ext.kotlin_version = '1.3.0' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.3.0' repositories { mavenCentral() -- cgit v1.2.3 From 87a204363bea8186cb1945e82ab7c62d6d782dab Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Sun, 8 Sep 2019 09:57:06 +0200 Subject: Update Kotlin version to 1.3.50 --- .travis.yml | 4 ++-- mockito-kotlin/build.gradle | 2 +- tests/build.gradle | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9b4a49e..925d366 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: - jdk: openjdk8 env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.50 - jdk: openjdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.40 + env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.50 - jdk: openjdk8 env: TERM=dumb KOTLIN_VERSION=1.0.7 - jdk: openjdk8 @@ -19,7 +19,7 @@ matrix: - jdk: openjdk8 env: TERM=dumb KOTLIN_VERSION=1.2.50 - jdk: openjdk8 - env: TERM=dumb KOTLIN_VERSION=1.3.40 + env: TERM=dumb KOTLIN_VERSION=1.3.50 env: diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 03f0515..7f5bc36 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -3,7 +3,7 @@ apply from: '../publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = "1.3.0" + ext.kotlin_version = "1.3.50" repositories { mavenCentral() diff --git a/tests/build.gradle b/tests/build.gradle index 8990624..cd11001 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.3.0' + ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.3.50' repositories { mavenCentral() -- cgit v1.2.3 From 8baf2db88dfc1f9e809c2caf5c0615010a2a2345 Mon Sep 17 00:00:00 2001 From: Niek Haarman Date: Fri, 5 Jul 2019 15:59:30 +0200 Subject: Support lenient in mock and withSettings --- .../kotlin/com/nhaarman/mockitokotlin2/Mocking.kt | 23 +++++++++++++++------- tests/src/test/kotlin/test/MockingTest.kt | 20 +++++++++++++++++-- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt index afc0773..521575b 100644 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt +++ b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt @@ -48,9 +48,10 @@ import kotlin.reflect.KClass * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + * @param lenient Lenient mocks bypass "strict stubbing" validation. */ inline fun mock( - extraInterfaces: Array>? = null, + extraInterfaces: Array>? = null, name: String? = null, spiedInstance: Any? = null, defaultAnswer: Answer? = null, @@ -60,7 +61,8 @@ inline fun mock( invocationListeners: Array? = null, stubOnly: Boolean = false, @Incubating useConstructor: UseConstructor? = null, - @Incubating outerInstance: Any? = null + @Incubating outerInstance: Any? = null, + @Incubating lenient: Boolean = false ): T { return Mockito.mock( T::class.java, @@ -75,7 +77,8 @@ inline fun mock( invocationListeners = invocationListeners, stubOnly = stubOnly, useConstructor = useConstructor, - outerInstance = outerInstance + outerInstance = outerInstance, + lenient = lenient ) )!! } @@ -94,9 +97,10 @@ inline fun mock( * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + * @param lenient Lenient mocks bypass "strict stubbing" validation. */ inline fun mock( - extraInterfaces: Array>? = null, + extraInterfaces: Array>? = null, name: String? = null, spiedInstance: Any? = null, defaultAnswer: Answer? = null, @@ -107,6 +111,7 @@ inline fun mock( stubOnly: Boolean = false, @Incubating useConstructor: UseConstructor? = null, @Incubating outerInstance: Any? = null, + @Incubating lenient: Boolean = false, stubbing: KStubbing.(T) -> Unit ): T { return Mockito.mock( @@ -122,7 +127,8 @@ inline fun mock( invocationListeners = invocationListeners, stubOnly = stubOnly, useConstructor = useConstructor, - outerInstance = outerInstance + outerInstance = outerInstance, + lenient = lenient ) ).apply { KStubbing(this).stubbing(this) }!! } @@ -142,9 +148,10 @@ inline fun mock( * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + * @param lenient Lenient mocks bypass "strict stubbing" validation. */ fun withSettings( - extraInterfaces: Array>? = null, + extraInterfaces: Array>? = null, name: String? = null, spiedInstance: Any? = null, defaultAnswer: Answer? = null, @@ -154,7 +161,8 @@ fun withSettings( invocationListeners: Array? = null, stubOnly: Boolean = false, @Incubating useConstructor: UseConstructor? = null, - @Incubating outerInstance: Any? = null + @Incubating outerInstance: Any? = null, + @Incubating lenient: Boolean = false ): MockSettings = Mockito.withSettings().apply { extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } name?.let { name(it) } @@ -167,6 +175,7 @@ fun withSettings( if (stubOnly) stubOnly() useConstructor?.let { useConstructor(*it.args) } outerInstance?.let { outerInstance(it) } + if (lenient) lenient() } class UseConstructor private constructor(val args: Array) { diff --git a/tests/src/test/kotlin/test/MockingTest.kt b/tests/src/test/kotlin/test/MockingTest.kt index 5a45d1e..0bb19ce 100644 --- a/tests/src/test/kotlin/test/MockingTest.kt +++ b/tests/src/test/kotlin/test/MockingTest.kt @@ -3,10 +3,12 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail -import com.nhaarman.mockitokotlin2.* -import com.nhaarman.mockitokotlin2.UseConstructor.Companion import com.nhaarman.mockitokotlin2.UseConstructor.Companion.parameterless import com.nhaarman.mockitokotlin2.UseConstructor.Companion.withArguments +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever import org.junit.Test import org.mockito.Mockito import org.mockito.exceptions.verification.WantedButNotInvoked @@ -255,6 +257,20 @@ class MockingTest : TestBase() { } } + @Test + fun mockStubbing_withSettingsAPIAndStubbing_name() { + /* Given */ + val mock = mock(name = "myName") { + on { nullableStringResult() } doReturn "foo" + } + + /* When */ + val result = mock.nullableStringResult() + + /* Then */ + expect(result).toBe("foo") + } + @Test fun mockStubbing_withSettingsAPI_defaultAnswer() { /* Given */ -- cgit v1.2.3 From b8f480fd5594d037a085da2d857bdd5597a56bdf Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Tue, 5 Jan 2021 13:44:08 +0000 Subject: Add acknowledgements section to the README (#399) Following the repository move into the GitHub Mockito organization, let's add an acknowledgements section to Niek for the original creation and extensive work that went into `mockito-kotlin`. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d8087af..c368163 100644 --- a/README.md +++ b/README.md @@ -65,3 +65,8 @@ Usually it is enough to test only using the default Kotlin versions; CI will test against multiple versions. If you want to test using a different Kotlin version locally, set an environment variable `KOTLIN_VERSION` and run the tests. + +### Acknowledgements + +`mockito-kotlin` was created and developed by [nhaarman@](https://github.com/nhaarman) after which the repository was integrated into the official Mockito GitHub organization. +We would like to thank Niek for the original idea and extensive work plus support that went into `mockito-kotlin`. -- cgit v1.2.3 From 8b97f9a6646d82f1377a70945d6c057822ab9184 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Sun, 17 Jan 2021 22:11:26 -0600 Subject: Initial GH Actions workflow --- .github/workflows/ci.yml | 104 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4094914 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +# +# CI build that assembles artifacts and runs tests. +# If validation is successful this workflow releases from the main dev branch. +# +# - skipping CI: add [skip ci] to the commit message +# - skipping release: add [skip release] to the commit message +# +name: CI + +on: + push: + branches: + - main + tags-ignore: + - v* # release tags are automatically generated after a successful CI build, no need to run CI against them + pull_request: + branches: + - main + +jobs: + + # + # SINGLE-JOB + # + verify: + runs-on: ubuntu-latest + if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')" + + steps: + + - name: 1. Check out code + uses: actions/checkout@v2 # https://github.com/actions/checkout + + - name: 2. Set up Java 8 + uses: actions/setup-java@v1 # https://github.com/actions/setup-java + with: + java-version: 8 + + - name: 3. Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 # https://github.com/gradle/wrapper-validation-action + + # + # Main build job + # + build: + needs: [verify] + runs-on: ubuntu-latest + + # Definition of the build matrix + strategy: + matrix: + mock-maker: ['mock-maker-default', 'mock-maker-inline'] + kotlin: ['1.0.7', '1.1.61', '1.2.50', '1.3.50'] + + steps: + + - name: 1. Check out code + uses: actions/checkout@v2 # https://github.com/actions/checkout + + - name: 2. Set up Java 8 + uses: actions/setup-java@v1 # https://github.com/actions/setup-java + with: + java-version: 8 + + - name: 3. Build with Kotlin ${{ matrix.kotlin }} and mock-maker ${{ matrix.mock-maker }} + run: | + ops/mockMakerInline.sh + ./gradlew build bintrayUpload idea -PbintrayDryRun + env: + KOTLIN_VERSION: ${{ matrix.kotlin }} + MOCK_MAKER: ${{ matrix.mock-maker }} + + # + # Release job, only for pushes to the main development branch + # + release: + runs-on: ubuntu-latest + needs: [build] # build job must pass before we can release + + if: github.event_name == 'push' + && github.ref == 'refs/heads/main' + && github.repository == 'mockito/mockito-kotlin' + && !contains(toJSON(github.event.commits.*.message), '[skip release]') + + steps: + + - name: Check out code + uses: actions/checkout@v2 # https://github.com/actions/checkout + with: + fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci + + - name: Set up Java 8 + uses: actions/setup-java@v1 + with: + java-version: 8 + + - name: Build and publish to Bintray/MavenCentral + run: ./gradlew tasks # TODO, in progress: bintrayUpload githubRelease +# env: +# GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} +# BINTRAY_API_KEY: ${{secrets.BINTRAY_API_KEY}} +# NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} +# NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}} + -- cgit v1.2.3 From 867e38640add2809f33fa5c0d8280c7897d1ce37 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Mon, 18 Jan 2021 08:48:40 -0600 Subject: Bumped Gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 54731 -> 56177 bytes gradle/wrapper/gradle-wrapper.properties | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 6b6ea3a..29953ea 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f2beea1..da9702f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Mon Oct 29 21:53:52 CET 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip -- cgit v1.2.3 From 50f284af6bbdc5e7d6f07f477dc88580c0b7ee6b Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Mon, 18 Jan 2021 09:04:32 -0600 Subject: Working on Shipkit integration --- .gitignore | 1 + build.gradle | 32 ++++++++++++--------- gradle/publishing.gradle | 67 +++++++++++++++++++++++++++++++++++++++++++ gradle/scripts/tagging.gradle | 22 -------------- mockito-kotlin/build.gradle | 6 ++-- publishing.gradle | 63 ---------------------------------------- tests/build.gradle | 2 +- version.properties | 3 ++ 8 files changed, 94 insertions(+), 102 deletions(-) create mode 100644 gradle/publishing.gradle delete mode 100644 gradle/scripts/tagging.gradle delete mode 100644 publishing.gradle create mode 100644 version.properties diff --git a/.gitignore b/.gitignore index bfee7ef..f9e1291 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .gradle build/ out/ +repo # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar diff --git a/build.gradle b/build.gradle index 40ac3cd..9de5a17 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,24 @@ -buildscript { - repositories { - maven { - url "https://plugins.gradle.org/m2/" - } - } - dependencies { - classpath "io.spring.gradle:spring-bintray-plugin:0.11.1" - } +plugins { + id "org.shipkit.shipkit-auto-version" version "1.1.1" + id "org.shipkit.shipkit-changelog" version "1.1.1" + id "org.shipkit.shipkit-github-release" version "1.1.1" } -plugins { - id 'com.github.ben-manes.versions' version '0.20.0' +//TODO: update the group to 'org.mockito' +group = 'com.nhaarman.mockito-kotlin2' + +tasks.named("generateChangelog") { + previousRevision = project.ext.'shipkit-auto-version.previous-tag' + githubToken = System.getenv("GITHUB_TOKEN") + repository = "mockito/mockito-kotlin" } -apply from: 'gradle/scripts/tagging.gradle' +tasks.named("githubRelease") { + def genTask = tasks.named("generateChangelog").get() + dependsOn genTask + repository = genTask.repository + changelog = genTask.outputFile + githubToken = System.getenv("GITHUB_TOKEN") + newTagRevision = System.getenv("GITHUB_SHA") +} -println ext.versionName \ No newline at end of file diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle new file mode 100644 index 0000000..716da43 --- /dev/null +++ b/gradle/publishing.gradle @@ -0,0 +1,67 @@ +apply plugin: 'maven-publish' + +//bintray.bintrayUser = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') +//bintray.bintrayKey = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') +//bintray.repo = 'maven' +//bintray.org = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') +//bintray.packageName = 'Mockito-Kotlin' +//bintray.publication = 'mavenJava' +// +//bintray.licenses = ['MIT'] +//bintray.ossrhUser = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') +//bintray.ossrhPassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') +//bintray.overrideOnUpload = false +//bintray.gpgPassphrase = hasProperty('signing_password') ? signing_password : System.getenv('SIGNING_PASSWORD') + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from 'build/javadoc' +} + +task sourceJar(type: Jar) { + from sourceSets.main.allSource +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifactId 'mockito-kotlin' + + from components.java + + artifact sourceJar { + classifier "sources" + } + + artifact javadocJar + + pom.withXml { + def root = asNode() + root.appendNode('name', 'Mockito-Kotlin') + root.appendNode('description', 'Using Mockito with Kotlin.') + root.appendNode('url', 'https://github.com/mockito/mockito-kotlin') + + def scm = root.appendNode('scm') + scm.appendNode('url', 'scm:git@github.com:mockito/mockito-kotlin.git') + + def licenses = root.appendNode('licenses') + def mitLicense = licenses.appendNode('license') + mitLicense.appendNode('name', 'MIT') + + def developers = root.appendNode('developers') + def nhaarman = developers.appendNode('developer') + nhaarman.appendNode('id', 'nhaarman') + nhaarman.appendNode('name', 'Niek Haarman') + } + } + } + + //useful for testing - running "publish" will create artifacts/pom in a local dir + repositories { maven { url = "$rootProject.buildDir/repo" } } +} + +// Avoid generation of the module metadata so that we don't have to publish an additional file +// and keep the build logic simple. +tasks.withType(GenerateModuleMetadata) { + enabled = false +} \ No newline at end of file diff --git a/gradle/scripts/tagging.gradle b/gradle/scripts/tagging.gradle deleted file mode 100644 index 907707d..0000000 --- a/gradle/scripts/tagging.gradle +++ /dev/null @@ -1,22 +0,0 @@ -new ByteArrayOutputStream().withStream { os -> - - exec { - commandLine 'git', 'describe', '--abbrev=0', '--tags' - standardOutput = os - } - - String tag = os.toString().trim(); - if (tag.length() == 0) { - tag = "0.0.0" - } else if (tag.indexOf('-') != -1 && tag.length() > tag.indexOf('-') + 1 && tag.charAt(tag.indexOf('-') + 1).isDigit()) { - tag = tag.substring(0, tag.indexOf('-')); - } - - ext.versionName = tag; - - if (isRelease == 'false') { - int lastNumber = Integer.parseInt(tag.substring(tag.size() - 1)) - ext.versionName = tag.substring(0, tag.size() - 1) + (lastNumber + 1) + "-SNAPSHOT"; - } -} - diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 7f5bc36..6b32f27 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'kotlin' -apply from: '../publishing.gradle' +apply from: '../gradle/publishing.gradle' apply plugin: 'org.jetbrains.dokka' buildscript { @@ -13,8 +13,8 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17" - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4" - classpath "com.github.dcendents:android-maven-gradle-plugin:2.1" + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5" + classpath "com.github.dcendents:android-maven-gradle-plugin:2.1" //TODO do we need android-maven-gradle-plugin? } } diff --git a/publishing.gradle b/publishing.gradle deleted file mode 100644 index cb03d87..0000000 --- a/publishing.gradle +++ /dev/null @@ -1,63 +0,0 @@ -apply plugin: 'maven-publish' -apply plugin: "io.spring.bintray" - -bintray.bintrayUser = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') -bintray.bintrayKey = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') -bintray.repo = 'maven' -bintray.org = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') -bintray.packageName = 'Mockito-Kotlin' -bintray.publication = 'mavenJava' - -bintray.licenses = ['MIT'] -bintray.ossrhUser = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') -bintray.ossrhPassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') -bintray.overrideOnUpload = false -bintray.gpgPassphrase = hasProperty('signing_password') ? signing_password : System.getenv('SIGNING_PASSWORD') - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from 'build/javadoc' -} - -task sourceJar(type: Jar) { - from sourceSets.main.allSource -} - -group = 'com.nhaarman.mockito-kotlin2' -version = rootProject.ext.versionName - -publishing { - publications { - mavenJava(MavenPublication) { - groupId 'com.nhaarman.mockitokotlin2' - artifactId 'mockito-kotlin' - - from components.java - - artifact sourceJar { - classifier "sources" - } - - artifact javadocJar - - pom.withXml { - def root = asNode() - root.appendNode('name', 'Mockito-Kotlin') - root.appendNode('description', 'Using Mockito with Kotlin.') - root.appendNode('url', 'https://github.com/nhaarman/mockito-kotlin') - - def scm = root.appendNode('scm') - scm.appendNode('url', 'scm:git@github.com:nhaarman/mockito-kotlin.git') - - def licenses = root.appendNode('licenses') - def mitLicense = licenses.appendNode('license') - mitLicense.appendNode('name', 'MIT') - - def developers = root.appendNode('developers') - def nhaarman = developers.appendNode('developer') - nhaarman.appendNode('id', 'nhaarman') - nhaarman.appendNode('name', 'Niek Haarman') - } - } - } -} \ No newline at end of file diff --git a/tests/build.gradle b/tests/build.gradle index cd11001..91da020 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -18,7 +18,7 @@ repositories { } dependencies { - compile files("${rootProject.projectDir}/mockito-kotlin/build/libs/mockito-kotlin-${rootProject.ext.versionName}.jar") + compile files("${rootProject.projectDir}/mockito-kotlin/build/libs/mockito-kotlin-${version}.jar") compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.mockito:mockito-core:2.23.0" diff --git a/version.properties b/version.properties new file mode 100644 index 0000000..d3be764 --- /dev/null +++ b/version.properties @@ -0,0 +1,3 @@ +# Version of the produced binaries. +# The version is inferred by shipkit-auto-version Gradle plugin (https://github.com/shipkit/shipkit-auto-version) +version=2.2.1-SNAPSHOT -- cgit v1.2.3 From 5624a10e2853d85b0ae10019819c5afefeedb4cf Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Sun, 24 Jan 2021 19:24:07 -0600 Subject: Enabled Bintray publications Tested by: - building artifacts locally and recursively comparing with the previously released artifacts/poms - published to 'test' repo on Bintray --- build.gradle | 3 --- gradle/publishing.gradle | 58 ++++++++++++++++++++++++++++++++++++++---------- version.properties | 2 +- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 9de5a17..3a07a83 100644 --- a/build.gradle +++ b/build.gradle @@ -4,9 +4,6 @@ plugins { id "org.shipkit.shipkit-github-release" version "1.1.1" } -//TODO: update the group to 'org.mockito' -group = 'com.nhaarman.mockito-kotlin2' - tasks.named("generateChangelog") { previousRevision = project.ext.'shipkit-auto-version.previous-tag' githubToken = System.getenv("GITHUB_TOKEN") diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index 716da43..00194a6 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -1,17 +1,7 @@ apply plugin: 'maven-publish' -//bintray.bintrayUser = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') -//bintray.bintrayKey = hasProperty('bintray_key') ? bintray_key : System.getenv('BINTRAY_KEY') -//bintray.repo = 'maven' -//bintray.org = hasProperty('bintray_username') ? bintray_username : System.getenv('BINTRAY_USER') -//bintray.packageName = 'Mockito-Kotlin' -//bintray.publication = 'mavenJava' -// -//bintray.licenses = ['MIT'] -//bintray.ossrhUser = hasProperty('sonatype_username') ? sonatype_username : System.getenv('SONATYPE_USERNAME') -//bintray.ossrhPassword = hasProperty('sonatype_password') ? sonatype_password : System.getenv('SONATYPE_PASSWORD') -//bintray.overrideOnUpload = false -//bintray.gpgPassphrase = hasProperty('signing_password') ? signing_password : System.getenv('SIGNING_PASSWORD') +//TODO: update the group to 'org.mockito' ***AND*** change java packages +group = 'com.nhaarman.mockitokotlin2' task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' @@ -60,8 +50,52 @@ publishing { repositories { maven { url = "$rootProject.buildDir/repo" } } } +clean { + delete "$rootProject.buildDir/repo" +} + // Avoid generation of the module metadata so that we don't have to publish an additional file // and keep the build logic simple. tasks.withType(GenerateModuleMetadata) { enabled = false +} + +//fleshes out problems with Maven pom generation when building +tasks.build.dependsOn('publishJavaLibraryPublicationToMavenLocal') + +//Bintray Gradle plugin configuration (https://github.com/bintray/gradle-bintray-plugin) +//Plugin jars are added to the buildscript classpath in the root build.gradle file +apply plugin: 'com.jfrog.bintray' + +bintray { + //We need to use some user id here, because the Bintray key is associated with the user + //However, any user id is good, so longer the user has necessary privileges to the repository + user = 'szczepiq' //https://bintray.com/szczepiq + key = System.getenv('BINTRAY_API_KEY') + publish = false //can be changed to 'false' for testing + dryRun = project.hasProperty('bintrayDryRun') + + publications = ['mavenJava'] + + pkg { + repo = 'test' //https://bintray.com/mockito/maven // TODO change to 'maaven' when CI ready + userOrg = 'mockito' //https://bintray.com/mockito + + name = 'mockito-kotlin' + + licenses = ['MIT'] + labels = ['kotlin', 'mockito'] + vcsUrl = 'https://github.com/mockito/mockito-kotlin.git' + + version { + name = project.version + vcsTag = "v$project.version" + + mavenCentralSync { + sync = false // TODO enable after CI+bintray integration is ready + user = System.getenv('NEXUS_TOKEN_USER') + password = System.getenv('NEXUS_TOKEN_PWD') + } + } + } } \ No newline at end of file diff --git a/version.properties b/version.properties index d3be764..8285f56 100644 --- a/version.properties +++ b/version.properties @@ -1,3 +1,3 @@ # Version of the produced binaries. # The version is inferred by shipkit-auto-version Gradle plugin (https://github.com/shipkit/shipkit-auto-version) -version=2.2.1-SNAPSHOT +version=2.3.0 -- cgit v1.2.3 From 23b53a8b2e66dbc3bb83c3193ecf7127de1370d8 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Mon, 25 Jan 2021 07:55:08 -0600 Subject: Fixed CI bugs --- .github/workflows/ci.yml | 6 +++--- gradle/publishing.gradle | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4094914..bd37f8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: - name: 3. Build with Kotlin ${{ matrix.kotlin }} and mock-maker ${{ matrix.mock-maker }} run: | ops/mockMakerInline.sh - ./gradlew build bintrayUpload idea -PbintrayDryRun + ./gradlew build bintrayUpload -PbintrayDryRun env: KOTLIN_VERSION: ${{ matrix.kotlin }} MOCK_MAKER: ${{ matrix.mock-maker }} @@ -96,8 +96,8 @@ jobs: - name: Build and publish to Bintray/MavenCentral run: ./gradlew tasks # TODO, in progress: bintrayUpload githubRelease -# env: -# GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} # BINTRAY_API_KEY: ${{secrets.BINTRAY_API_KEY}} # NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} # NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}} diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index 00194a6..722f59a 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -14,7 +14,7 @@ task sourceJar(type: Jar) { publishing { publications { - mavenJava(MavenPublication) { + javaLibrary(MavenPublication) { artifactId 'mockito-kotlin' from components.java @@ -75,7 +75,7 @@ bintray { publish = false //can be changed to 'false' for testing dryRun = project.hasProperty('bintrayDryRun') - publications = ['mavenJava'] + publications = ['javaLibrary'] pkg { repo = 'test' //https://bintray.com/mockito/maven // TODO change to 'maaven' when CI ready -- cgit v1.2.3 From 8744735a9429fe04e41f22546365b3f77ba6e8c3 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Mon, 25 Jan 2021 07:56:00 -0600 Subject: Deleted Travis CI --- .travis.yml | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 925d366..0000000 --- a/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -sudo: false - -language: java - -matrix: - include: - - jdk: openjdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.0.7 - - jdk: openjdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.1.61 - - jdk: openjdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.2.50 - - jdk: openjdk8 - env: TERM=dumb MOCK_MAKER=mock-maker-inline KOTLIN_VERSION=1.3.50 - - jdk: openjdk8 - env: TERM=dumb KOTLIN_VERSION=1.0.7 - - jdk: openjdk8 - env: TERM=dumb KOTLIN_VERSION=1.1.61 - - jdk: openjdk8 - env: TERM=dumb KOTLIN_VERSION=1.2.50 - - jdk: openjdk8 - env: TERM=dumb KOTLIN_VERSION=1.3.50 - - -env: - matrix: - - TERM=dumb - -install: - - true - -script: - - ops/mockMakerInline.sh - - ./gradlew clean - - ./gradlew assemble - - ./gradlew test -i - -notifications: - email: false -- cgit v1.2.3 From 28263afc737e8e6b5e370a864c99181edd767b8c Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Mon, 25 Jan 2021 08:22:03 -0600 Subject: Debuggability, disabled old Kotlin versions --- .github/workflows/ci.yml | 4 +++- tests/build.gradle | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd37f8a..2328c48 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,9 @@ jobs: strategy: matrix: mock-maker: ['mock-maker-default', 'mock-maker-inline'] - kotlin: ['1.0.7', '1.1.61', '1.2.50', '1.3.50'] + kotlin: ['1.3.50', '1.4.21'] + # Note that the old Travis CI referenced other Kotlin versions: '1.0.7', '1.1.61', '1.2.50' + # However, those versions of Kotlin don't work with latest Gradle steps: diff --git a/tests/build.gradle b/tests/build.gradle index 91da020..24ab716 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -1,5 +1,6 @@ buildscript { ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.3.50' + println "$project uses Kotlin $kotlin_version" repositories { mavenCentral() -- cgit v1.2.3 From aebeba66c0593a509ce0c612d83da829849520f8 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Mon, 25 Jan 2021 08:33:45 -0600 Subject: Removed unused plugin --- mockito-kotlin/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 6b32f27..0e44297 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -14,7 +14,6 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17" classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5" - classpath "com.github.dcendents:android-maven-gradle-plugin:2.1" //TODO do we need android-maven-gradle-plugin? } } -- cgit v1.2.3 From bc9618fa08ef6f36c68e20ac02293851650149ad Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Wed, 27 Jan 2021 10:19:05 -0600 Subject: Bumped Gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 53 +++++++++++++++++++------------ gradlew.bat | 43 ++++++++++++++----------- 4 files changed, 58 insertions(+), 40 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 29953ea..e708b1c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index da9702f..28ff446 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d..4f906e0 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -66,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -109,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -138,19 +156,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index e95643d..ac1b06f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -- cgit v1.2.3 From e74292d85c0e7b27e628d778440bd4c421883a9e Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Wed, 27 Jan 2021 11:32:21 -0600 Subject: Enabled releases to GitHub and Bintray --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2328c48..18a37f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,10 +97,10 @@ jobs: java-version: 8 - name: Build and publish to Bintray/MavenCentral - run: ./gradlew tasks # TODO, in progress: bintrayUpload githubRelease + run: ./gradlew githubRelease bintrayUpload env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} -# BINTRAY_API_KEY: ${{secrets.BINTRAY_API_KEY}} -# NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} -# NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}} + BINTRAY_API_KEY: ${{secrets.BINTRAY_API_KEY}} + NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} + NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}} -- cgit v1.2.3 From 147adc85bf34b613f0161ff15c302bbe29dbf964 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Sat, 13 Mar 2021 16:17:32 -0600 Subject: Automated releases --- .github/workflows/ci.yml | 10 +++++----- RELEASING.md | 6 ++---- build.gradle | 18 ++++++++++++++++-- gradle/publishing.gradle | 42 +++++------------------------------------- mockito-kotlin/build.gradle | 1 - 5 files changed, 28 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18a37f8..3dd06af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: - name: 3. Build with Kotlin ${{ matrix.kotlin }} and mock-maker ${{ matrix.mock-maker }} run: | ops/mockMakerInline.sh - ./gradlew build bintrayUpload -PbintrayDryRun + ./gradlew build env: KOTLIN_VERSION: ${{ matrix.kotlin }} MOCK_MAKER: ${{ matrix.mock-maker }} @@ -96,11 +96,11 @@ jobs: with: java-version: 8 - - name: Build and publish to Bintray/MavenCentral - run: ./gradlew githubRelease bintrayUpload + - name: Build and release + run: ./gradlew githubRelease publishToSonatype # closeAndReleaseStagingRepository env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - BINTRAY_API_KEY: ${{secrets.BINTRAY_API_KEY}} NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}} - + PGP_KEY: ${{secrets.PGP_KEY}} + PGP_PWD: ${{secrets.PGP_PWD}} diff --git a/RELEASING.md b/RELEASING.md index f1eb2d6..3f0140c 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,5 +1,3 @@ -To publish a release: +# Releasing - - Tag the commit on master: `git tag -a x.x.x -m x.x.x && git push --tags` - - Execute the release process: `./gradlew clean test bintraySign mavenCentralSync -PisRelease=true` - - Don't forget to publish the tag on Github with release notes :) \ No newline at end of file +Every change on the main development branch is released to Maven Central. \ No newline at end of file diff --git a/build.gradle b/build.gradle index 3a07a83..8d74f9b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,13 @@ plugins { id "org.shipkit.shipkit-auto-version" version "1.1.1" - id "org.shipkit.shipkit-changelog" version "1.1.1" - id "org.shipkit.shipkit-github-release" version "1.1.1" + id "org.shipkit.shipkit-changelog" version "1.1.10" + id "org.shipkit.shipkit-github-release" version "1.1.10" + id "io.github.gradle-nexus.publish-plugin" version "1.0.0" } +//TODO: change java packages to "org.mockito.kotlin" +group = 'org.mockito.kotlin' + tasks.named("generateChangelog") { previousRevision = project.ext.'shipkit-auto-version.previous-tag' githubToken = System.getenv("GITHUB_TOKEN") @@ -19,3 +23,13 @@ tasks.named("githubRelease") { newTagRevision = System.getenv("GITHUB_SHA") } +nexusPublishing { + repositories { + if (System.getenv("NEXUS_TOKEN_PWD")) { + sonatype { + username = System.getenv("NEXUS_TOKEN_USER") + password = System.getenv("NEXUS_TOKEN_PWD") + } + } + } +} diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index 722f59a..6bb5f1a 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -1,8 +1,5 @@ apply plugin: 'maven-publish' -//TODO: update the group to 'org.mockito' ***AND*** change java packages -group = 'com.nhaarman.mockitokotlin2' - task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from 'build/javadoc' @@ -63,39 +60,10 @@ tasks.withType(GenerateModuleMetadata) { //fleshes out problems with Maven pom generation when building tasks.build.dependsOn('publishJavaLibraryPublicationToMavenLocal') -//Bintray Gradle plugin configuration (https://github.com/bintray/gradle-bintray-plugin) -//Plugin jars are added to the buildscript classpath in the root build.gradle file -apply plugin: 'com.jfrog.bintray' - -bintray { - //We need to use some user id here, because the Bintray key is associated with the user - //However, any user id is good, so longer the user has necessary privileges to the repository - user = 'szczepiq' //https://bintray.com/szczepiq - key = System.getenv('BINTRAY_API_KEY') - publish = false //can be changed to 'false' for testing - dryRun = project.hasProperty('bintrayDryRun') - - publications = ['javaLibrary'] - - pkg { - repo = 'test' //https://bintray.com/mockito/maven // TODO change to 'maaven' when CI ready - userOrg = 'mockito' //https://bintray.com/mockito - - name = 'mockito-kotlin' - - licenses = ['MIT'] - labels = ['kotlin', 'mockito'] - vcsUrl = 'https://github.com/mockito/mockito-kotlin.git' - - version { - name = project.version - vcsTag = "v$project.version" - - mavenCentralSync { - sync = false // TODO enable after CI+bintray integration is ready - user = System.getenv('NEXUS_TOKEN_USER') - password = System.getenv('NEXUS_TOKEN_PWD') - } - } +apply plugin: 'signing' //https://docs.gradle.org/current/userguide/signing_plugin.html +signing { + if (System.getenv("PGP_KEY")) { + useInMemoryPgpKeys(System.getenv("PGP_KEY"), System.getenv("PGP_PWD")) + sign publishing.publications.javaLibrary } } \ No newline at end of file diff --git a/mockito-kotlin/build.gradle b/mockito-kotlin/build.gradle index 0e44297..6c726db 100644 --- a/mockito-kotlin/build.gradle +++ b/mockito-kotlin/build.gradle @@ -13,7 +13,6 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17" - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5" } } -- cgit v1.2.3 From e740c576e46b2391c3a7b9a9394949cc041a81e7 Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Tue, 16 Mar 2021 13:49:10 +0000 Subject: Rename packages to org.mockito.kotlin --- README.md | 6 +- .../com/nhaarman/mockitokotlin2/ArgumentCaptor.kt | 212 ----------------- .../com/nhaarman/mockitokotlin2/BDDMockito.kt | 81 ------- .../com/nhaarman/mockitokotlin2/KStubbing.kt | 84 ------- .../kotlin/com/nhaarman/mockitokotlin2/Matchers.kt | 139 ----------- .../kotlin/com/nhaarman/mockitokotlin2/Mocking.kt | 211 ----------------- .../kotlin/com/nhaarman/mockitokotlin2/Mockito.kt | 41 ---- .../mockitokotlin2/MockitoKotlinException.kt | 28 --- .../com/nhaarman/mockitokotlin2/OngoingStubbing.kt | 126 ---------- .../kotlin/com/nhaarman/mockitokotlin2/Spying.kt | 62 ----- .../kotlin/com/nhaarman/mockitokotlin2/Stubber.kt | 65 ----- .../com/nhaarman/mockitokotlin2/Verification.kt | 263 --------------------- .../com/nhaarman/mockitokotlin2/VerifyScope.kt | 48 ---- .../mockitokotlin2/internal/CreateInstance.kt | 56 ----- .../kotlin/org/mockito/kotlin/ArgumentCaptor.kt | 212 +++++++++++++++++ .../main/kotlin/org/mockito/kotlin/BDDMockito.kt | 81 +++++++ .../main/kotlin/org/mockito/kotlin/KStubbing.kt | 84 +++++++ .../src/main/kotlin/org/mockito/kotlin/Matchers.kt | 139 +++++++++++ .../src/main/kotlin/org/mockito/kotlin/Mocking.kt | 211 +++++++++++++++++ .../src/main/kotlin/org/mockito/kotlin/Mockito.kt | 41 ++++ .../org/mockito/kotlin/MockitoKotlinException.kt | 28 +++ .../kotlin/org/mockito/kotlin/OngoingStubbing.kt | 126 ++++++++++ .../src/main/kotlin/org/mockito/kotlin/Spying.kt | 62 +++++ .../src/main/kotlin/org/mockito/kotlin/Stubber.kt | 65 +++++ .../main/kotlin/org/mockito/kotlin/Verification.kt | 263 +++++++++++++++++++++ .../main/kotlin/org/mockito/kotlin/VerifyScope.kt | 48 ++++ .../org/mockito/kotlin/internal/CreateInstance.kt | 56 +++++ .../src/test/kotlin/test/CoroutinesTest.kt | 2 +- tests/src/test/kotlin/test/ArgumentCaptorTest.kt | 2 +- tests/src/test/kotlin/test/BDDMockitoTest.kt | 4 +- tests/src/test/kotlin/test/EqTest.kt | 4 +- tests/src/test/kotlin/test/MatchersTest.kt | 3 +- tests/src/test/kotlin/test/MockingTest.kt | 12 +- tests/src/test/kotlin/test/OngoingStubbingTest.kt | 3 +- tests/src/test/kotlin/test/SpyTest.kt | 2 +- tests/src/test/kotlin/test/StubberTest.kt | 2 +- tests/src/test/kotlin/test/VerificationTest.kt | 3 +- tests/src/test/kotlin/test/VerifyTest.kt | 6 +- .../kotlin/test/createinstance/NullCasterTest.kt | 2 +- .../kotlin/test/inline/UsingMockMakerInlineTest.kt | 2 +- 40 files changed, 1444 insertions(+), 1441 deletions(-) delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt delete mode 100644 mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/BDDMockito.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KStubbing.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Matchers.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mocking.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mockito.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/MockitoKotlinException.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/OngoingStubbing.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Spying.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Stubber.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Verification.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/VerifyScope.kt create mode 100644 mockito-kotlin/src/main/kotlin/org/mockito/kotlin/internal/CreateInstance.kt diff --git a/README.md b/README.md index c368163..3d43db7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Mockito-Kotlin -[ ![Download](https://maven-badges.herokuapp.com/maven-central/com.nhaarman.mockitokotlin2/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/com.nhaarman.mockitokotlin2/mockito-kotlin) +[ ![Download](https://maven-badges.herokuapp.com/maven-central/org.mockito/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/org.mockito/mockito-kotlin) A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. @@ -9,7 +9,7 @@ Mockito-Kotlin is available on Maven Central and JCenter. For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` with the latest version: ```groovy -testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x" +testImplementation "org.mockito:mockito-kotlin:x.x.x" ``` ## Example @@ -33,7 +33,7 @@ fun doAction_doesSomething(){ } ``` -For more info and samples, see the [Wiki](https://github.com/nhaarman/mockito-kotlin/wiki). +For more info and samples, see the [Wiki](https://github.com/mockito/mockito-kotlin/wiki). ## Building diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt deleted file mode 100644 index be69337..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/ArgumentCaptor.kt +++ /dev/null @@ -1,212 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import com.nhaarman.mockitokotlin2.internal.createInstance -import org.mockito.ArgumentCaptor -import kotlin.reflect.KClass - -/** - * Creates a [KArgumentCaptor] for given type. - */ -inline fun argumentCaptor(): KArgumentCaptor { - return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) -} - -/** - * Creates 2 [KArgumentCaptor]s for given types. - */ -inline fun argumentCaptor( - a: KClass = A::class, - b: KClass = B::class -): Pair, KArgumentCaptor> { - return Pair( - KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), - KArgumentCaptor(ArgumentCaptor.forClass(b.java), b) - ) -} - -/** - * Creates 3 [KArgumentCaptor]s for given types. - */ -inline fun argumentCaptor( - a: KClass = A::class, - b: KClass = B::class, - c: KClass = C::class -): Triple, KArgumentCaptor, KArgumentCaptor> { - return Triple( - KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), - KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), - KArgumentCaptor(ArgumentCaptor.forClass(c.java), c) - ) -} - -class ArgumentCaptorHolder4( - val first: A, - val second: B, - val third: C, - val fourth: D -) { - - operator fun component1() = first - operator fun component2() = second - operator fun component3() = third - operator fun component4() = fourth -} - -class ArgumentCaptorHolder5( - val first: A, - val second: B, - val third: C, - val fourth: D, - val fifth: E -) { - - operator fun component1() = first - operator fun component2() = second - operator fun component3() = third - operator fun component4() = fourth - operator fun component5() = fifth -} - - -/** - * Creates 4 [KArgumentCaptor]s for given types. - */ -inline fun argumentCaptor( - a: KClass = A::class, - b: KClass = B::class, - c: KClass = C::class, - d: KClass = D::class -): ArgumentCaptorHolder4, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { - return ArgumentCaptorHolder4( - KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), - KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), - KArgumentCaptor(ArgumentCaptor.forClass(c.java), c), - KArgumentCaptor(ArgumentCaptor.forClass(d.java), d) - ) -} - -/** - * Creates 4 [KArgumentCaptor]s for given types. - */ -inline fun argumentCaptor( - a: KClass = A::class, - b: KClass = B::class, - c: KClass = C::class, - d: KClass = D::class, - e: KClass = E::class -): ArgumentCaptorHolder5, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { - return ArgumentCaptorHolder5( - KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), - KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), - KArgumentCaptor(ArgumentCaptor.forClass(c.java), c), - KArgumentCaptor(ArgumentCaptor.forClass(d.java), d), - KArgumentCaptor(ArgumentCaptor.forClass(e.java), e) - ) -} - -/** - * Creates a [KArgumentCaptor] for given type, taking in a lambda to allow fast verification. - */ -inline fun argumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor { - return argumentCaptor().apply(f) -} - -/** - * Creates a [KArgumentCaptor] for given nullable type. - */ -inline fun nullableArgumentCaptor(): KArgumentCaptor { - return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) -} - -/** - * Creates a [KArgumentCaptor] for given nullable type, taking in a lambda to allow fast verification. - */ -inline fun nullableArgumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor { - return nullableArgumentCaptor().apply(f) -} - -/** - * Alias for [ArgumentCaptor.capture]. - */ -inline fun capture(captor: ArgumentCaptor): T { - return captor.capture() ?: createInstance() -} - -class KArgumentCaptor( - private val captor: ArgumentCaptor, - private val tClass: KClass<*> -) { - - /** - * The first captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val firstValue: T - get() = captor.firstValue - - /** - * The second captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val secondValue: T - get() = captor.secondValue - - /** - * The third captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val thirdValue: T - get() = captor.thirdValue - - /** - * The last captured value of the argument. - * @throws IndexOutOfBoundsException if the value is not available. - */ - val lastValue: T - get() = captor.lastValue - - val allValues: List - get() = captor.allValues - - @Suppress("UNCHECKED_CAST") - fun capture(): T { - return captor.capture() ?: createInstance(tClass) as T - } -} - -val ArgumentCaptor.firstValue: T - get() = allValues[0] - -val ArgumentCaptor.secondValue: T - get() = allValues[1] - -val ArgumentCaptor.thirdValue: T - get() = allValues[2] - -val ArgumentCaptor.lastValue: T - get() = allValues.last() diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt deleted file mode 100644 index ead224d..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/BDDMockito.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import org.mockito.BDDMockito -import org.mockito.BDDMockito.BDDMyOngoingStubbing -import org.mockito.invocation.InvocationOnMock -import org.mockito.stubbing.Answer - -/** - * Alias for [BDDMockito.given]. - */ -fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing { - return BDDMockito.given(methodCall) -} - -/** - * Alias for [BDDMockito.given] with a lambda. - */ -fun given(methodCall: () -> T): BDDMyOngoingStubbing { - return given(methodCall()) -} - -/** - * Alias for [BDDMockito.then]. - */ -fun then(mock: T): BDDMockito.Then { - return BDDMockito.then(mock) -} - -/** - * Alias for [BDDMyOngoingStubbing.will] - * */ -infix fun BDDMyOngoingStubbing.will(value: Answer): BDDMockito.BDDMyOngoingStubbing { - return will(value) -} - -/** - * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a lambda. - */ -infix fun BDDMyOngoingStubbing.willAnswer(value: (InvocationOnMock) -> T?): BDDMockito.BDDMyOngoingStubbing { - return willAnswer { value(it) } -} - -/** - * Alias for [BBDMyOngoingStubbing.willReturn]. - */ -infix fun BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing { - return willReturn(value()) -} - -/** - * Alias for [BBDMyOngoingStubbing.willThrow]. - */ -infix fun BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing { - return willThrow(value()) -} - diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt deleted file mode 100644 index 4844240..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/KStubbing.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import com.nhaarman.mockitokotlin2.internal.createInstance -import kotlinx.coroutines.runBlocking -import org.mockito.Mockito -import org.mockito.stubbing.OngoingStubbing -import kotlin.reflect.KClass - - -inline fun stubbing( - mock: T, - stubbing: KStubbing.(T) -> Unit -) { - KStubbing(mock).stubbing(mock) -} - -inline fun T.stub(stubbing: KStubbing.(T) -> Unit): T { - return apply { KStubbing(this).stubbing(this) } -} - -class KStubbing(val mock: T) { - - fun on(methodCall: R): OngoingStubbing = Mockito.`when`(methodCall) - - fun onGeneric(methodCall: T.() -> R?, c: KClass): OngoingStubbing { - val r = try { - mock.methodCall() - } catch (e: NullPointerException) { - // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a - // null value for a non-nullable generic type. - // We catch this NPE to return a valid instance. - // The Mockito state has already been modified at this point to reflect - // the wanted changes. - createInstance(c) - } - return Mockito.`when`(r) - } - - inline fun onGeneric(noinline methodCall: T.() -> R?): OngoingStubbing { - return onGeneric(methodCall, R::class) - } - - fun on(methodCall: T.() -> R): OngoingStubbing { - return try { - Mockito.`when`(mock.methodCall()) - } catch (e: NullPointerException) { - throw MockitoKotlinException( - "NullPointerException thrown when stubbing.\nThis may be due to two reasons:\n\t- The method you're trying to stub threw an NPE: look at the stack trace below;\n\t- You're trying to stub a generic method: try `onGeneric` instead.", - e - ) - } - } - - fun KStubbing.onBlocking( - m: suspend T.() -> R - ): OngoingStubbing { - return runBlocking { Mockito.`when`(mock.m()) } - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt deleted file mode 100644 index 1d89902..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Matchers.kt +++ /dev/null @@ -1,139 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import com.nhaarman.mockitokotlin2.internal.createInstance -import org.mockito.ArgumentMatcher -import org.mockito.Mockito - -/** Object argument that is equal to the given value. */ -fun eq(value: T): T { - return Mockito.eq(value) ?: value -} - -/** Object argument that is the same as the given value. */ -fun same(value: T): T { - return Mockito.same(value) ?: value -} - -/** Matches any object, excluding nulls. */ -inline fun any(): T { - return Mockito.any(T::class.java) ?: createInstance() -} - -/** Matches anything, including nulls. */ -inline fun anyOrNull(): T { - return Mockito.any() ?: createInstance() -} - -/** Matches any vararg object, including nulls. */ -inline fun anyVararg(): T { - return Mockito.any() ?: createInstance() -} - -/** Matches any array of type T. */ -inline fun anyArray(): Array { - return Mockito.any(Array::class.java) ?: arrayOf() -} - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. - */ -inline fun argThat(noinline predicate: T.() -> Boolean): T { - return Mockito.argThat { arg: T? -> arg?.predicate() ?: false } ?: createInstance( - T::class - ) -} - -/** - * Registers a custom ArgumentMatcher. The original Mockito function registers the matcher and returns null, - * here the required type is returned. - * - * @param matcher The ArgumentMatcher on [T] to be registered. - */ -inline fun argThat(matcher: ArgumentMatcher): T { - return Mockito.argThat(matcher) ?: createInstance() -} - -/** - * Alias for [argThat]. - * - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. - */ -inline fun argForWhich(noinline predicate: T.() -> Boolean): T { - return argThat(predicate) -} - -/** - * Creates a custom argument matcher. - * `null` values will never evaluate to `true`. - * - * @param predicate A function that returns `true` when given [T] matches the predicate. - */ -inline fun argWhere(noinline predicate: (T) -> Boolean): T { - return argThat(predicate) -} - -/** - * Argument that implements the given class. - */ -inline fun isA(): T { - return Mockito.isA(T::class.java) ?: createInstance() -} - -/** - * `null` argument. - */ -fun isNull(): T? = Mockito.isNull() - -/** - * Not `null` argument. - */ -fun isNotNull(): T? { - return Mockito.isNotNull() -} - -/** - * Not `null` argument. - */ -fun notNull(): T? { - return Mockito.notNull() -} - -/** - * Object argument that is reflection-equal to the given value with support for excluding - * selected fields from a class. - */ -inline fun refEq(value: T, vararg excludeFields: String): T { - return Mockito.refEq(value, *excludeFields) ?: createInstance() -} - diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt deleted file mode 100644 index 521575b..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt +++ /dev/null @@ -1,211 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import org.mockito.Incubating -import org.mockito.MockSettings -import org.mockito.Mockito -import org.mockito.listeners.InvocationListener -import org.mockito.mock.SerializableMode -import org.mockito.stubbing.Answer -import kotlin.DeprecationLevel.ERROR -import kotlin.reflect.KClass - -/** - * Creates a mock for [T]. - * - * @param extraInterfaces Specifies extra interfaces the mock should implement. - * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. - * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. - * @param defaultAnswer Specifies default answers to interactions. - * @param serializable Configures the mock to be serializable. - * @param serializableMode Configures the mock to be serializable with a specific serializable mode. - * @param verboseLogging Enables real-time logging of method invocations on this mock. - * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. - * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. - * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. - * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. - * @param lenient Lenient mocks bypass "strict stubbing" validation. - */ -inline fun mock( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: UseConstructor? = null, - @Incubating outerInstance: Any? = null, - @Incubating lenient: Boolean = false -): T { - return Mockito.mock( - T::class.java, - withSettings( - extraInterfaces = extraInterfaces, - name = name, - spiedInstance = spiedInstance, - defaultAnswer = defaultAnswer, - serializable = serializable, - serializableMode = serializableMode, - verboseLogging = verboseLogging, - invocationListeners = invocationListeners, - stubOnly = stubOnly, - useConstructor = useConstructor, - outerInstance = outerInstance, - lenient = lenient - ) - )!! -} - -/** - * Creates a mock for [T], allowing for immediate stubbing. - * - * @param extraInterfaces Specifies extra interfaces the mock should implement. - * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. - * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. - * @param defaultAnswer Specifies default answers to interactions. - * @param serializable Configures the mock to be serializable. - * @param serializableMode Configures the mock to be serializable with a specific serializable mode. - * @param verboseLogging Enables real-time logging of method invocations on this mock. - * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. - * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. - * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. - * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. - * @param lenient Lenient mocks bypass "strict stubbing" validation. - */ -inline fun mock( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: UseConstructor? = null, - @Incubating outerInstance: Any? = null, - @Incubating lenient: Boolean = false, - stubbing: KStubbing.(T) -> Unit -): T { - return Mockito.mock( - T::class.java, - withSettings( - extraInterfaces = extraInterfaces, - name = name, - spiedInstance = spiedInstance, - defaultAnswer = defaultAnswer, - serializable = serializable, - serializableMode = serializableMode, - verboseLogging = verboseLogging, - invocationListeners = invocationListeners, - stubOnly = stubOnly, - useConstructor = useConstructor, - outerInstance = outerInstance, - lenient = lenient - ) - ).apply { KStubbing(this).stubbing(this) }!! -} - -/** - * Allows mock creation with additional mock settings. - * See [MockSettings]. - * - * @param extraInterfaces Specifies extra interfaces the mock should implement. - * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. - * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. - * @param defaultAnswer Specifies default answers to interactions. - * @param serializable Configures the mock to be serializable. - * @param serializableMode Configures the mock to be serializable with a specific serializable mode. - * @param verboseLogging Enables real-time logging of method invocations on this mock. - * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. - * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. - * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. - * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. - * @param lenient Lenient mocks bypass "strict stubbing" validation. - */ -fun withSettings( - extraInterfaces: Array>? = null, - name: String? = null, - spiedInstance: Any? = null, - defaultAnswer: Answer? = null, - serializable: Boolean = false, - serializableMode: SerializableMode? = null, - verboseLogging: Boolean = false, - invocationListeners: Array? = null, - stubOnly: Boolean = false, - @Incubating useConstructor: UseConstructor? = null, - @Incubating outerInstance: Any? = null, - @Incubating lenient: Boolean = false -): MockSettings = Mockito.withSettings().apply { - extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } - name?.let { name(it) } - spiedInstance?.let { spiedInstance(it) } - defaultAnswer?.let { defaultAnswer(it) } - if (serializable) serializable() - serializableMode?.let { serializable(it) } - if (verboseLogging) verboseLogging() - invocationListeners?.let { invocationListeners(*it) } - if (stubOnly) stubOnly() - useConstructor?.let { useConstructor(*it.args) } - outerInstance?.let { outerInstance(it) } - if (lenient) lenient() -} - -class UseConstructor private constructor(val args: Array) { - - companion object { - - /** Invokes the parameterless constructor. */ - fun parameterless() = UseConstructor(emptyArray()) - - /** Invokes a constructor with given arguments. */ - fun withArguments(vararg arguments: Any): UseConstructor { - return UseConstructor(arguments.asList().toTypedArray()) - } - } -} - -@Deprecated( - "Use mock() with optional arguments instead.", - ReplaceWith("mock(defaultAnswer = a)"), - level = ERROR -) -inline fun mock(a: Answer): T = mock(defaultAnswer = a) - -@Deprecated( - "Use mock() with optional arguments instead.", - ReplaceWith("mock(name = s)"), - level = ERROR -) -inline fun mock(s: String): T = mock(name = s) - -@Suppress("DeprecatedCallableAddReplaceWith") -@Deprecated("Use mock() with optional arguments instead.", level = ERROR) -inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt deleted file mode 100644 index 3f52873..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mockito.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import org.mockito.MockingDetails -import org.mockito.Mockito - -fun validateMockitoUsage() { - Mockito.validateMockitoUsage() -} - -fun reset(vararg mocks: T) { - Mockito.reset(*mocks) -} - -fun mockingDetails(toInspect: Any): MockingDetails { - return Mockito.mockingDetails(toInspect)!! -} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt deleted file mode 100644 index d079b8f..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/MockitoKotlinException.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -class MockitoKotlinException(message: String?, cause: Throwable?) : RuntimeException(message, cause) diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt deleted file mode 100644 index 5ec16be..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/OngoingStubbing.kt +++ /dev/null @@ -1,126 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import org.mockito.Mockito -import org.mockito.invocation.InvocationOnMock -import org.mockito.stubbing.Answer -import org.mockito.stubbing.OngoingStubbing -import kotlin.DeprecationLevel.ERROR -import kotlin.reflect.KClass - - -/** - * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called. - * - * Alias for [Mockito.when]. - */ -@Suppress("NOTHING_TO_INLINE") -inline fun whenever(methodCall: T): OngoingStubbing { - return Mockito.`when`(methodCall)!! -} - -/** - * Sets a return value to be returned when the method is called. - * - * Alias for [OngoingStubbing.thenReturn]. - */ -infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing { - return thenReturn(t) -} - -/** - * Sets consecutive return values to be returned when the method is called. - * - * Alias for [OngoingStubbing.thenReturn]. - */ -fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing { - return thenReturn(t, *ts) -} - -/** - * Sets consecutive return values to be returned when the method is called. - */ -inline infix fun OngoingStubbing.doReturnConsecutively(ts: List): OngoingStubbing { - return thenReturn( - ts[0], - *ts.drop(1).toTypedArray() - ) -} - -/** - * Sets Throwable objects to be thrown when the method is called. - * - * Alias for [OngoingStubbing.thenThrow]. - */ -infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing { - return thenThrow(t) -} - -/** - * Sets Throwable objects to be thrown when the method is called. - * - * Alias for [OngoingStubbing.doThrow]. - */ -fun OngoingStubbing.doThrow( - t: Throwable, - vararg ts: Throwable -): OngoingStubbing { - return thenThrow(t, *ts) -} - -/** - * Sets a Throwable type to be thrown when the method is called. - */ -infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing { - return thenThrow(t.java) -} - -/** - * Sets Throwable classes to be thrown when the method is called. - */ -fun OngoingStubbing.doThrow( - t: KClass, - vararg ts: KClass -): OngoingStubbing { - return thenThrow(t.java, *ts.map { it.java }.toTypedArray()) -} - -/** - * Sets a generic Answer for the method. - * - * Alias for [OngoingStubbing.thenAnswer]. - */ -infix fun OngoingStubbing.doAnswer(answer: Answer<*>): OngoingStubbing { - return thenAnswer(answer) -} - -/** - * Sets a generic Answer for the method using a lambda. - */ -infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing { - return thenAnswer(answer) -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt deleted file mode 100644 index 340c562..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Spying.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import org.mockito.Mockito - - -/** - * Creates a spy of the real object. - * The spy calls real methods unless they are stubbed. - */ -inline fun spy(): T { - return Mockito.spy(T::class.java)!! -} - -/** - * Creates a spy of the real object, allowing for immediate stubbing. - * The spy calls real methods unless they are stubbed. - */ -inline fun spy(stubbing: KStubbing.(T) -> Unit): T { - return Mockito.spy(T::class.java) - .apply { KStubbing(this).stubbing(this) }!! -} - -/** - * Creates a spy of the real object. The spy calls real methods unless they are stubbed. - */ -fun spy(value: T): T { - return Mockito.spy(value)!! -} - -/** - * Creates a spy of the real object, allowing for immediate stubbing. - * The spy calls real methods unless they are stubbed. - */ -inline fun spy(value: T, stubbing: KStubbing.(T) -> Unit): T { - return spy(value) - .apply { KStubbing(this).stubbing(this) }!! -} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt deleted file mode 100644 index a6aee54..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Stubber.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import org.mockito.Mockito -import org.mockito.invocation.InvocationOnMock -import org.mockito.stubbing.Stubber -import kotlin.reflect.KClass - - -fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber { - return Mockito.doAnswer { answer(it) }!! -} - -fun doCallRealMethod(): Stubber { - return Mockito.doCallRealMethod()!! -} - -fun doNothing(): Stubber { - return Mockito.doNothing()!! -} - -fun doReturn(value: Any?): Stubber { - return Mockito.doReturn(value)!! -} - -fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber { - return Mockito.doReturn( - toBeReturned, - *toBeReturnedNext - )!! -} - -fun doThrow(toBeThrown: KClass): Stubber { - return Mockito.doThrow(toBeThrown.java)!! -} - -fun doThrow(vararg toBeThrown: Throwable): Stubber { - return Mockito.doThrow(*toBeThrown)!! -} - -fun Stubber.whenever(mock: T) = `when`(mock) \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt deleted file mode 100644 index b8e124c..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Verification.kt +++ /dev/null @@ -1,263 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - -import com.nhaarman.mockitokotlin2.internal.createInstance -import kotlinx.coroutines.runBlocking -import org.mockito.InOrder -import org.mockito.Mockito -import org.mockito.verification.VerificationAfterDelay -import org.mockito.verification.VerificationMode -import org.mockito.verification.VerificationWithTimeout - -/** - * Verifies certain behavior happened once. - * - * Alias for [Mockito.verify]. - */ -fun verify(mock: T): T { - return Mockito.verify(mock)!! -} - -/** - * Verifies certain suspending behavior happened once. - * - * Warning: Only one method call can be verified in the function. - * Subsequent method calls are ignored! - */ -fun verifyBlocking(mock: T, f: suspend T.() -> Unit) { - val m = Mockito.verify(mock) - runBlocking { m.f() } -} - -/** - * Verifies certain behavior happened at least once / exact number of times / never. - * - * Warning: Only one method call can be verified in the function. - * Subsequent method calls are ignored! - */ -fun verifyBlocking(mock: T, mode: VerificationMode, f: suspend T.() -> Unit) { - val m = Mockito.verify(mock, mode) - runBlocking { m.f() } -} -/** - * Verifies certain behavior happened at least once / exact number of times / never. - * - * Alias for [Mockito.verify]. - */ -fun verify(mock: T, mode: VerificationMode): T { - return Mockito.verify(mock, mode)!! -} - -/** - * Checks if any of given mocks has any unverified interaction. - * - * Alias for [Mockito.verifyNoMoreInteractions]. - */ -fun verifyNoMoreInteractions(vararg mocks: T) { - Mockito.verifyNoMoreInteractions(*mocks) -} - -/** - * Verifies that no interactions happened on given mocks beyond the previously verified interactions. - * - * Alias for [Mockito.verifyZeroInteractions]. - */ -fun verifyZeroInteractions(vararg mocks: Any) { - Mockito.verifyZeroInteractions(*mocks) -} - -/** - * Allows verifying exact number of invocations. - * - * Alias for [Mockito.times]. - */ -fun times(numInvocations: Int): VerificationMode { - return Mockito.times(numInvocations)!! -} - -/** - * Allows at-least-x verification. - * - * Alias for [Mockito.atLeast]. - */ -fun atLeast(numInvocations: Int): VerificationMode { - return Mockito.atLeast(numInvocations)!! -} - -/** - * Allows at-least-once verification. - * - * Alias for [Mockito.atLeastOnce]. - */ -fun atLeastOnce(): VerificationMode { - return Mockito.atLeastOnce()!! -} - -/** - * Allows at-most-x verification. - * - * Alias for [Mockito.atMost]. - */ -fun atMost(maxNumberOfInvocations: Int): VerificationMode { - return Mockito.atMost(maxNumberOfInvocations)!! -} - -/** - * Allows non-greedy verification in order. - * - * Alias for [Mockito.calls]. - */ -fun calls(wantedNumberOfInvocations: Int): VerificationMode { - return Mockito.calls(wantedNumberOfInvocations)!! -} - -/** - * Alias for [times] with parameter `0`. - */ -fun never(): VerificationMode { - return Mockito.never()!! -} - -/** - * Use this method in order to only clear invocations, when stubbing is non-trivial. - * - * Alias for [Mockito.clearInvocations]. - */ -fun clearInvocations(vararg mocks: T) { - Mockito.clearInvocations(*mocks) -} - -/** - * Adds a description to be printed if verification fails. - * - * Alias for [Mockito.description]. - */ -fun description(description: String): VerificationMode { - return Mockito.description(description) -} - -/** - * Allows verifying over a given period. It causes a verify to wait for a specified period of time for a desired - * interaction rather than failing immediately if has not already happened. May be useful for testing in concurrent - * conditions. - */ -fun after(millis: Long): VerificationAfterDelay { - return Mockito.after(millis)!! -} - -/** - * Allows verifying with timeout. It causes a verify to wait for a specified period of time for a desired - * interaction rather than fails immediately if has not already happened. May be useful for testing in concurrent - * conditions. - */ -fun timeout(millis: Long): VerificationWithTimeout { - return Mockito.timeout(millis)!! -} - -/** - * Ignores stubbed methods of given mocks for the sake of verification. - * - * Alias for [Mockito.ignoreStubs]. - */ -fun ignoreStubs(vararg mocks: Any): Array { - return Mockito.ignoreStubs(*mocks)!! -} - -/** - * Creates [InOrder] object that allows verifying mocks in order. - * - * Alias for [Mockito.inOrder]. - */ -fun inOrder(vararg mocks: Any): InOrder { - return Mockito.inOrder(*mocks)!! -} - -/** - * Creates [InOrder] object that allows verifying mocks in order. - * Accepts a lambda to allow easy evaluation. - * - * Alias for [Mockito.inOrder]. - */ -inline fun inOrder( - vararg mocks: Any, - evaluation: InOrder.() -> Unit -) { - Mockito.inOrder(*mocks).evaluation() -} - -/** - * Allows [InOrder] verification for a single mocked instance: - * - * mock.inOrder { - * verify().foo() - * } - * - */ -inline fun T.inOrder(block: InOrderOnType.() -> Any) { - block.invoke(InOrderOnType(this)) -} - -class InOrderOnType(private val t: T) : InOrder by inOrder(t as Any) { - - fun verify(): T = verify(t) -} - -/** - * Allows checking if given method was the only one invoked. - */ -fun only(): VerificationMode { - return Mockito.only()!! -} - - -/** - * For usage with verification only. - * - * For example: - * verify(myObject).doSomething(check { assertThat(it, is("Test")) }) - * - * @param predicate A function that performs actions to verify an argument [T]. - */ -inline fun check(noinline predicate: (T) -> Unit): T { - return Mockito.argThat { arg: T? -> - if (arg == null) error( - """The argument passed to the predicate was null. - -If you are trying to verify an argument to be null, use `isNull()`. -If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. -""".trimIndent() - ) - - try { - predicate(arg) - true - } catch (e: Error) { - e.printStackTrace() - false - } - } ?: createInstance(T::class) -} diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt deleted file mode 100644 index 6ef3c33..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/VerifyScope.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2 - - -/** - * Verify multiple calls on mock - * Supports an easier to read style of - * - * ``` - * verify(mock) { - * 2 * { call() } - * } - * ``` - */ -inline fun verify(mock: T, block: VerifyScope.() -> Unit) { - VerifyScope(mock).block() -} - -class VerifyScope(val mock: T) { - - operator inline fun Int.times(call: T.() -> Unit) { - verify(mock, com.nhaarman.mockitokotlin2.times(this)).call() - } -} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt deleted file mode 100644 index 4d9b5f5..0000000 --- a/mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/internal/CreateInstance.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2018 Niek Haarman - * Copyright (c) 2007 Mockito contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.nhaarman.mockitokotlin2.internal - -import kotlin.reflect.KClass -import java.lang.reflect.Array as JavaArray - -inline fun createInstance(): T { - return when (T::class) { - Boolean::class -> false as T - Byte::class -> 0.toByte() as T - Char::class -> 0.toChar() as T - Short::class -> 0.toShort() as T - Int::class -> 0 as T - Long::class -> 0L as T - Float::class -> 0f as T - Double::class -> 0.0 as T - else -> createInstance(T::class) - } -} - -fun createInstance(kClass: KClass): T { - return castNull() -} - -/** - * Uses a quirk in the bytecode generated by Kotlin - * to cast [null] to a non-null type. - * - * See https://youtrack.jetbrains.com/issue/KT-8135. - */ -@Suppress("UNCHECKED_CAST") -private fun castNull(): T = null as T diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt new file mode 100644 index 0000000..253a58c --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt @@ -0,0 +1,212 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.kotlin.internal.createInstance +import org.mockito.ArgumentCaptor +import kotlin.reflect.KClass + +/** + * Creates a [KArgumentCaptor] for given type. + */ +inline fun argumentCaptor(): KArgumentCaptor { + return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) +} + +/** + * Creates 2 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class +): Pair, KArgumentCaptor> { + return Pair( + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b) + ) +} + +/** + * Creates 3 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class, + c: KClass = C::class +): Triple, KArgumentCaptor, KArgumentCaptor> { + return Triple( + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), + KArgumentCaptor(ArgumentCaptor.forClass(c.java), c) + ) +} + +class ArgumentCaptorHolder4( + val first: A, + val second: B, + val third: C, + val fourth: D +) { + + operator fun component1() = first + operator fun component2() = second + operator fun component3() = third + operator fun component4() = fourth +} + +class ArgumentCaptorHolder5( + val first: A, + val second: B, + val third: C, + val fourth: D, + val fifth: E +) { + + operator fun component1() = first + operator fun component2() = second + operator fun component3() = third + operator fun component4() = fourth + operator fun component5() = fifth +} + + +/** + * Creates 4 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class, + c: KClass = C::class, + d: KClass = D::class +): ArgumentCaptorHolder4, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { + return ArgumentCaptorHolder4( + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), + KArgumentCaptor(ArgumentCaptor.forClass(c.java), c), + KArgumentCaptor(ArgumentCaptor.forClass(d.java), d) + ) +} + +/** + * Creates 4 [KArgumentCaptor]s for given types. + */ +inline fun argumentCaptor( + a: KClass = A::class, + b: KClass = B::class, + c: KClass = C::class, + d: KClass = D::class, + e: KClass = E::class +): ArgumentCaptorHolder5, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> { + return ArgumentCaptorHolder5( + KArgumentCaptor(ArgumentCaptor.forClass(a.java), a), + KArgumentCaptor(ArgumentCaptor.forClass(b.java), b), + KArgumentCaptor(ArgumentCaptor.forClass(c.java), c), + KArgumentCaptor(ArgumentCaptor.forClass(d.java), d), + KArgumentCaptor(ArgumentCaptor.forClass(e.java), e) + ) +} + +/** + * Creates a [KArgumentCaptor] for given type, taking in a lambda to allow fast verification. + */ +inline fun argumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor { + return argumentCaptor().apply(f) +} + +/** + * Creates a [KArgumentCaptor] for given nullable type. + */ +inline fun nullableArgumentCaptor(): KArgumentCaptor { + return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class) +} + +/** + * Creates a [KArgumentCaptor] for given nullable type, taking in a lambda to allow fast verification. + */ +inline fun nullableArgumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor { + return nullableArgumentCaptor().apply(f) +} + +/** + * Alias for [ArgumentCaptor.capture]. + */ +inline fun capture(captor: ArgumentCaptor): T { + return captor.capture() ?: createInstance() +} + +class KArgumentCaptor( + private val captor: ArgumentCaptor, + private val tClass: KClass<*> +) { + + /** + * The first captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val firstValue: T + get() = captor.firstValue + + /** + * The second captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val secondValue: T + get() = captor.secondValue + + /** + * The third captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val thirdValue: T + get() = captor.thirdValue + + /** + * The last captured value of the argument. + * @throws IndexOutOfBoundsException if the value is not available. + */ + val lastValue: T + get() = captor.lastValue + + val allValues: List + get() = captor.allValues + + @Suppress("UNCHECKED_CAST") + fun capture(): T { + return captor.capture() ?: createInstance(tClass) as T + } +} + +val ArgumentCaptor.firstValue: T + get() = allValues[0] + +val ArgumentCaptor.secondValue: T + get() = allValues[1] + +val ArgumentCaptor.thirdValue: T + get() = allValues[2] + +val ArgumentCaptor.lastValue: T + get() = allValues.last() diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/BDDMockito.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/BDDMockito.kt new file mode 100644 index 0000000..867f4c1 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/BDDMockito.kt @@ -0,0 +1,81 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.BDDMockito +import org.mockito.BDDMockito.BDDMyOngoingStubbing +import org.mockito.invocation.InvocationOnMock +import org.mockito.stubbing.Answer + +/** + * Alias for [BDDMockito.given]. + */ +fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing { + return BDDMockito.given(methodCall) +} + +/** + * Alias for [BDDMockito.given] with a lambda. + */ +fun given(methodCall: () -> T): BDDMyOngoingStubbing { + return given(methodCall()) +} + +/** + * Alias for [BDDMockito.then]. + */ +fun then(mock: T): BDDMockito.Then { + return BDDMockito.then(mock) +} + +/** + * Alias for [BDDMyOngoingStubbing.will] + * */ +infix fun BDDMyOngoingStubbing.will(value: Answer): BDDMockito.BDDMyOngoingStubbing { + return will(value) +} + +/** + * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a lambda. + */ +infix fun BDDMyOngoingStubbing.willAnswer(value: (InvocationOnMock) -> T?): BDDMockito.BDDMyOngoingStubbing { + return willAnswer { value(it) } +} + +/** + * Alias for [BBDMyOngoingStubbing.willReturn]. + */ +infix fun BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing { + return willReturn(value()) +} + +/** + * Alias for [BBDMyOngoingStubbing.willThrow]. + */ +infix fun BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing { + return willThrow(value()) +} + diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KStubbing.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KStubbing.kt new file mode 100644 index 0000000..bbf36bf --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KStubbing.kt @@ -0,0 +1,84 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.kotlin.internal.createInstance +import kotlinx.coroutines.runBlocking +import org.mockito.Mockito +import org.mockito.stubbing.OngoingStubbing +import kotlin.reflect.KClass + + +inline fun stubbing( + mock: T, + stubbing: KStubbing.(T) -> Unit +) { + KStubbing(mock).stubbing(mock) +} + +inline fun T.stub(stubbing: KStubbing.(T) -> Unit): T { + return apply { KStubbing(this).stubbing(this) } +} + +class KStubbing(val mock: T) { + + fun on(methodCall: R): OngoingStubbing = Mockito.`when`(methodCall) + + fun onGeneric(methodCall: T.() -> R?, c: KClass): OngoingStubbing { + val r = try { + mock.methodCall() + } catch (e: NullPointerException) { + // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a + // null value for a non-nullable generic type. + // We catch this NPE to return a valid instance. + // The Mockito state has already been modified at this point to reflect + // the wanted changes. + createInstance(c) + } + return Mockito.`when`(r) + } + + inline fun onGeneric(noinline methodCall: T.() -> R?): OngoingStubbing { + return onGeneric(methodCall, R::class) + } + + fun on(methodCall: T.() -> R): OngoingStubbing { + return try { + Mockito.`when`(mock.methodCall()) + } catch (e: NullPointerException) { + throw MockitoKotlinException( + "NullPointerException thrown when stubbing.\nThis may be due to two reasons:\n\t- The method you're trying to stub threw an NPE: look at the stack trace below;\n\t- You're trying to stub a generic method: try `onGeneric` instead.", + e + ) + } + } + + fun KStubbing.onBlocking( + m: suspend T.() -> R + ): OngoingStubbing { + return runBlocking { Mockito.`when`(mock.m()) } + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Matchers.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Matchers.kt new file mode 100644 index 0000000..a17da95 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Matchers.kt @@ -0,0 +1,139 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.kotlin.internal.createInstance +import org.mockito.ArgumentMatcher +import org.mockito.Mockito + +/** Object argument that is equal to the given value. */ +fun eq(value: T): T { + return Mockito.eq(value) ?: value +} + +/** Object argument that is the same as the given value. */ +fun same(value: T): T { + return Mockito.same(value) ?: value +} + +/** Matches any object, excluding nulls. */ +inline fun any(): T { + return Mockito.any(T::class.java) ?: createInstance() +} + +/** Matches anything, including nulls. */ +inline fun anyOrNull(): T { + return Mockito.any() ?: createInstance() +} + +/** Matches any vararg object, including nulls. */ +inline fun anyVararg(): T { + return Mockito.any() ?: createInstance() +} + +/** Matches any array of type T. */ +inline fun anyArray(): Array { + return Mockito.any(Array::class.java) ?: arrayOf() +} + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ +inline fun argThat(noinline predicate: T.() -> Boolean): T { + return Mockito.argThat { arg: T? -> arg?.predicate() ?: false } ?: createInstance( + T::class + ) +} + +/** + * Registers a custom ArgumentMatcher. The original Mockito function registers the matcher and returns null, + * here the required type is returned. + * + * @param matcher The ArgumentMatcher on [T] to be registered. + */ +inline fun argThat(matcher: ArgumentMatcher): T { + return Mockito.argThat(matcher) ?: createInstance() +} + +/** + * Alias for [argThat]. + * + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate. + */ +inline fun argForWhich(noinline predicate: T.() -> Boolean): T { + return argThat(predicate) +} + +/** + * Creates a custom argument matcher. + * `null` values will never evaluate to `true`. + * + * @param predicate A function that returns `true` when given [T] matches the predicate. + */ +inline fun argWhere(noinline predicate: (T) -> Boolean): T { + return argThat(predicate) +} + +/** + * Argument that implements the given class. + */ +inline fun isA(): T { + return Mockito.isA(T::class.java) ?: createInstance() +} + +/** + * `null` argument. + */ +fun isNull(): T? = Mockito.isNull() + +/** + * Not `null` argument. + */ +fun isNotNull(): T? { + return Mockito.isNotNull() +} + +/** + * Not `null` argument. + */ +fun notNull(): T? { + return Mockito.notNull() +} + +/** + * Object argument that is reflection-equal to the given value with support for excluding + * selected fields from a class. + */ +inline fun refEq(value: T, vararg excludeFields: String): T { + return Mockito.refEq(value, *excludeFields) ?: createInstance() +} + diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mocking.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mocking.kt new file mode 100644 index 0000000..9f6acd2 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mocking.kt @@ -0,0 +1,211 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.Incubating +import org.mockito.MockSettings +import org.mockito.Mockito +import org.mockito.listeners.InvocationListener +import org.mockito.mock.SerializableMode +import org.mockito.stubbing.Answer +import kotlin.DeprecationLevel.ERROR +import kotlin.reflect.KClass + +/** + * Creates a mock for [T]. + * + * @param extraInterfaces Specifies extra interfaces the mock should implement. + * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. + * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. + * @param defaultAnswer Specifies default answers to interactions. + * @param serializable Configures the mock to be serializable. + * @param serializableMode Configures the mock to be serializable with a specific serializable mode. + * @param verboseLogging Enables real-time logging of method invocations on this mock. + * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. + * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. + * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. + * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + * @param lenient Lenient mocks bypass "strict stubbing" validation. + */ +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: UseConstructor? = null, + @Incubating outerInstance: Any? = null, + @Incubating lenient: Boolean = false +): T { + return Mockito.mock( + T::class.java, + withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance, + lenient = lenient + ) + )!! +} + +/** + * Creates a mock for [T], allowing for immediate stubbing. + * + * @param extraInterfaces Specifies extra interfaces the mock should implement. + * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. + * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. + * @param defaultAnswer Specifies default answers to interactions. + * @param serializable Configures the mock to be serializable. + * @param serializableMode Configures the mock to be serializable with a specific serializable mode. + * @param verboseLogging Enables real-time logging of method invocations on this mock. + * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. + * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. + * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. + * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + * @param lenient Lenient mocks bypass "strict stubbing" validation. + */ +inline fun mock( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: UseConstructor? = null, + @Incubating outerInstance: Any? = null, + @Incubating lenient: Boolean = false, + stubbing: KStubbing.(T) -> Unit +): T { + return Mockito.mock( + T::class.java, + withSettings( + extraInterfaces = extraInterfaces, + name = name, + spiedInstance = spiedInstance, + defaultAnswer = defaultAnswer, + serializable = serializable, + serializableMode = serializableMode, + verboseLogging = verboseLogging, + invocationListeners = invocationListeners, + stubOnly = stubOnly, + useConstructor = useConstructor, + outerInstance = outerInstance, + lenient = lenient + ) + ).apply { KStubbing(this).stubbing(this) }!! +} + +/** + * Allows mock creation with additional mock settings. + * See [MockSettings]. + * + * @param extraInterfaces Specifies extra interfaces the mock should implement. + * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors. + * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks. + * @param defaultAnswer Specifies default answers to interactions. + * @param serializable Configures the mock to be serializable. + * @param serializableMode Configures the mock to be serializable with a specific serializable mode. + * @param verboseLogging Enables real-time logging of method invocations on this mock. + * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called. + * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations. + * @param useConstructor Mockito attempts to use constructor when creating instance of the mock. + * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor]. + * @param lenient Lenient mocks bypass "strict stubbing" validation. + */ +fun withSettings( + extraInterfaces: Array>? = null, + name: String? = null, + spiedInstance: Any? = null, + defaultAnswer: Answer? = null, + serializable: Boolean = false, + serializableMode: SerializableMode? = null, + verboseLogging: Boolean = false, + invocationListeners: Array? = null, + stubOnly: Boolean = false, + @Incubating useConstructor: UseConstructor? = null, + @Incubating outerInstance: Any? = null, + @Incubating lenient: Boolean = false +): MockSettings = Mockito.withSettings().apply { + extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) } + name?.let { name(it) } + spiedInstance?.let { spiedInstance(it) } + defaultAnswer?.let { defaultAnswer(it) } + if (serializable) serializable() + serializableMode?.let { serializable(it) } + if (verboseLogging) verboseLogging() + invocationListeners?.let { invocationListeners(*it) } + if (stubOnly) stubOnly() + useConstructor?.let { useConstructor(*it.args) } + outerInstance?.let { outerInstance(it) } + if (lenient) lenient() +} + +class UseConstructor private constructor(val args: Array) { + + companion object { + + /** Invokes the parameterless constructor. */ + fun parameterless() = UseConstructor(emptyArray()) + + /** Invokes a constructor with given arguments. */ + fun withArguments(vararg arguments: Any): UseConstructor { + return UseConstructor(arguments.asList().toTypedArray()) + } + } +} + +@Deprecated( + "Use mock() with optional arguments instead.", + ReplaceWith("mock(defaultAnswer = a)"), + level = ERROR +) +inline fun mock(a: Answer): T = mock(defaultAnswer = a) + +@Deprecated( + "Use mock() with optional arguments instead.", + ReplaceWith("mock(name = s)"), + level = ERROR +) +inline fun mock(s: String): T = mock(name = s) + +@Suppress("DeprecatedCallableAddReplaceWith") +@Deprecated("Use mock() with optional arguments instead.", level = ERROR) +inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!! \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mockito.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mockito.kt new file mode 100644 index 0000000..0f80e0c --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mockito.kt @@ -0,0 +1,41 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.MockingDetails +import org.mockito.Mockito + +fun validateMockitoUsage() { + Mockito.validateMockitoUsage() +} + +fun reset(vararg mocks: T) { + Mockito.reset(*mocks) +} + +fun mockingDetails(toInspect: Any): MockingDetails { + return Mockito.mockingDetails(toInspect)!! +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/MockitoKotlinException.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/MockitoKotlinException.kt new file mode 100644 index 0000000..3e209ae --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/MockitoKotlinException.kt @@ -0,0 +1,28 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +class MockitoKotlinException(message: String?, cause: Throwable?) : RuntimeException(message, cause) diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/OngoingStubbing.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/OngoingStubbing.kt new file mode 100644 index 0000000..3d97ce1 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/OngoingStubbing.kt @@ -0,0 +1,126 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.Mockito +import org.mockito.invocation.InvocationOnMock +import org.mockito.stubbing.Answer +import org.mockito.stubbing.OngoingStubbing +import kotlin.DeprecationLevel.ERROR +import kotlin.reflect.KClass + + +/** + * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called. + * + * Alias for [Mockito.when]. + */ +@Suppress("NOTHING_TO_INLINE") +inline fun whenever(methodCall: T): OngoingStubbing { + return Mockito.`when`(methodCall)!! +} + +/** + * Sets a return value to be returned when the method is called. + * + * Alias for [OngoingStubbing.thenReturn]. + */ +infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing { + return thenReturn(t) +} + +/** + * Sets consecutive return values to be returned when the method is called. + * + * Alias for [OngoingStubbing.thenReturn]. + */ +fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing { + return thenReturn(t, *ts) +} + +/** + * Sets consecutive return values to be returned when the method is called. + */ +inline infix fun OngoingStubbing.doReturnConsecutively(ts: List): OngoingStubbing { + return thenReturn( + ts[0], + *ts.drop(1).toTypedArray() + ) +} + +/** + * Sets Throwable objects to be thrown when the method is called. + * + * Alias for [OngoingStubbing.thenThrow]. + */ +infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing { + return thenThrow(t) +} + +/** + * Sets Throwable objects to be thrown when the method is called. + * + * Alias for [OngoingStubbing.doThrow]. + */ +fun OngoingStubbing.doThrow( + t: Throwable, + vararg ts: Throwable +): OngoingStubbing { + return thenThrow(t, *ts) +} + +/** + * Sets a Throwable type to be thrown when the method is called. + */ +infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing { + return thenThrow(t.java) +} + +/** + * Sets Throwable classes to be thrown when the method is called. + */ +fun OngoingStubbing.doThrow( + t: KClass, + vararg ts: KClass +): OngoingStubbing { + return thenThrow(t.java, *ts.map { it.java }.toTypedArray()) +} + +/** + * Sets a generic Answer for the method. + * + * Alias for [OngoingStubbing.thenAnswer]. + */ +infix fun OngoingStubbing.doAnswer(answer: Answer<*>): OngoingStubbing { + return thenAnswer(answer) +} + +/** + * Sets a generic Answer for the method using a lambda. + */ +infix fun OngoingStubbing.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing { + return thenAnswer(answer) +} diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Spying.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Spying.kt new file mode 100644 index 0000000..55fa9c0 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Spying.kt @@ -0,0 +1,62 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.Mockito + + +/** + * Creates a spy of the real object. + * The spy calls real methods unless they are stubbed. + */ +inline fun spy(): T { + return Mockito.spy(T::class.java)!! +} + +/** + * Creates a spy of the real object, allowing for immediate stubbing. + * The spy calls real methods unless they are stubbed. + */ +inline fun spy(stubbing: KStubbing.(T) -> Unit): T { + return Mockito.spy(T::class.java) + .apply { KStubbing(this).stubbing(this) }!! +} + +/** + * Creates a spy of the real object. The spy calls real methods unless they are stubbed. + */ +fun spy(value: T): T { + return Mockito.spy(value)!! +} + +/** + * Creates a spy of the real object, allowing for immediate stubbing. + * The spy calls real methods unless they are stubbed. + */ +inline fun spy(value: T, stubbing: KStubbing.(T) -> Unit): T { + return spy(value) + .apply { KStubbing(this).stubbing(this) }!! +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Stubber.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Stubber.kt new file mode 100644 index 0000000..fb417fc --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Stubber.kt @@ -0,0 +1,65 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.Mockito +import org.mockito.invocation.InvocationOnMock +import org.mockito.stubbing.Stubber +import kotlin.reflect.KClass + + +fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber { + return Mockito.doAnswer { answer(it) }!! +} + +fun doCallRealMethod(): Stubber { + return Mockito.doCallRealMethod()!! +} + +fun doNothing(): Stubber { + return Mockito.doNothing()!! +} + +fun doReturn(value: Any?): Stubber { + return Mockito.doReturn(value)!! +} + +fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber { + return Mockito.doReturn( + toBeReturned, + *toBeReturnedNext + )!! +} + +fun doThrow(toBeThrown: KClass): Stubber { + return Mockito.doThrow(toBeThrown.java)!! +} + +fun doThrow(vararg toBeThrown: Throwable): Stubber { + return Mockito.doThrow(*toBeThrown)!! +} + +fun Stubber.whenever(mock: T) = `when`(mock) \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Verification.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Verification.kt new file mode 100644 index 0000000..e79dd92 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Verification.kt @@ -0,0 +1,263 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + +import org.mockito.kotlin.internal.createInstance +import kotlinx.coroutines.runBlocking +import org.mockito.InOrder +import org.mockito.Mockito +import org.mockito.verification.VerificationAfterDelay +import org.mockito.verification.VerificationMode +import org.mockito.verification.VerificationWithTimeout + +/** + * Verifies certain behavior happened once. + * + * Alias for [Mockito.verify]. + */ +fun verify(mock: T): T { + return Mockito.verify(mock)!! +} + +/** + * Verifies certain suspending behavior happened once. + * + * Warning: Only one method call can be verified in the function. + * Subsequent method calls are ignored! + */ +fun verifyBlocking(mock: T, f: suspend T.() -> Unit) { + val m = Mockito.verify(mock) + runBlocking { m.f() } +} + +/** + * Verifies certain behavior happened at least once / exact number of times / never. + * + * Warning: Only one method call can be verified in the function. + * Subsequent method calls are ignored! + */ +fun verifyBlocking(mock: T, mode: VerificationMode, f: suspend T.() -> Unit) { + val m = Mockito.verify(mock, mode) + runBlocking { m.f() } +} +/** + * Verifies certain behavior happened at least once / exact number of times / never. + * + * Alias for [Mockito.verify]. + */ +fun verify(mock: T, mode: VerificationMode): T { + return Mockito.verify(mock, mode)!! +} + +/** + * Checks if any of given mocks has any unverified interaction. + * + * Alias for [Mockito.verifyNoMoreInteractions]. + */ +fun verifyNoMoreInteractions(vararg mocks: T) { + Mockito.verifyNoMoreInteractions(*mocks) +} + +/** + * Verifies that no interactions happened on given mocks beyond the previously verified interactions. + * + * Alias for [Mockito.verifyZeroInteractions]. + */ +fun verifyZeroInteractions(vararg mocks: Any) { + Mockito.verifyZeroInteractions(*mocks) +} + +/** + * Allows verifying exact number of invocations. + * + * Alias for [Mockito.times]. + */ +fun times(numInvocations: Int): VerificationMode { + return Mockito.times(numInvocations)!! +} + +/** + * Allows at-least-x verification. + * + * Alias for [Mockito.atLeast]. + */ +fun atLeast(numInvocations: Int): VerificationMode { + return Mockito.atLeast(numInvocations)!! +} + +/** + * Allows at-least-once verification. + * + * Alias for [Mockito.atLeastOnce]. + */ +fun atLeastOnce(): VerificationMode { + return Mockito.atLeastOnce()!! +} + +/** + * Allows at-most-x verification. + * + * Alias for [Mockito.atMost]. + */ +fun atMost(maxNumberOfInvocations: Int): VerificationMode { + return Mockito.atMost(maxNumberOfInvocations)!! +} + +/** + * Allows non-greedy verification in order. + * + * Alias for [Mockito.calls]. + */ +fun calls(wantedNumberOfInvocations: Int): VerificationMode { + return Mockito.calls(wantedNumberOfInvocations)!! +} + +/** + * Alias for [times] with parameter `0`. + */ +fun never(): VerificationMode { + return Mockito.never()!! +} + +/** + * Use this method in order to only clear invocations, when stubbing is non-trivial. + * + * Alias for [Mockito.clearInvocations]. + */ +fun clearInvocations(vararg mocks: T) { + Mockito.clearInvocations(*mocks) +} + +/** + * Adds a description to be printed if verification fails. + * + * Alias for [Mockito.description]. + */ +fun description(description: String): VerificationMode { + return Mockito.description(description) +} + +/** + * Allows verifying over a given period. It causes a verify to wait for a specified period of time for a desired + * interaction rather than failing immediately if has not already happened. May be useful for testing in concurrent + * conditions. + */ +fun after(millis: Long): VerificationAfterDelay { + return Mockito.after(millis)!! +} + +/** + * Allows verifying with timeout. It causes a verify to wait for a specified period of time for a desired + * interaction rather than fails immediately if has not already happened. May be useful for testing in concurrent + * conditions. + */ +fun timeout(millis: Long): VerificationWithTimeout { + return Mockito.timeout(millis)!! +} + +/** + * Ignores stubbed methods of given mocks for the sake of verification. + * + * Alias for [Mockito.ignoreStubs]. + */ +fun ignoreStubs(vararg mocks: Any): Array { + return Mockito.ignoreStubs(*mocks)!! +} + +/** + * Creates [InOrder] object that allows verifying mocks in order. + * + * Alias for [Mockito.inOrder]. + */ +fun inOrder(vararg mocks: Any): InOrder { + return Mockito.inOrder(*mocks)!! +} + +/** + * Creates [InOrder] object that allows verifying mocks in order. + * Accepts a lambda to allow easy evaluation. + * + * Alias for [Mockito.inOrder]. + */ +inline fun inOrder( + vararg mocks: Any, + evaluation: InOrder.() -> Unit +) { + Mockito.inOrder(*mocks).evaluation() +} + +/** + * Allows [InOrder] verification for a single mocked instance: + * + * mock.inOrder { + * verify().foo() + * } + * + */ +inline fun T.inOrder(block: InOrderOnType.() -> Any) { + block.invoke(InOrderOnType(this)) +} + +class InOrderOnType(private val t: T) : InOrder by inOrder(t as Any) { + + fun verify(): T = verify(t) +} + +/** + * Allows checking if given method was the only one invoked. + */ +fun only(): VerificationMode { + return Mockito.only()!! +} + + +/** + * For usage with verification only. + * + * For example: + * verify(myObject).doSomething(check { assertThat(it, is("Test")) }) + * + * @param predicate A function that performs actions to verify an argument [T]. + */ +inline fun check(noinline predicate: (T) -> Unit): T { + return Mockito.argThat { arg: T? -> + if (arg == null) error( + """The argument passed to the predicate was null. + +If you are trying to verify an argument to be null, use `isNull()`. +If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead. +""".trimIndent() + ) + + try { + predicate(arg) + true + } catch (e: Error) { + e.printStackTrace() + false + } + } ?: createInstance(T::class) +} diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/VerifyScope.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/VerifyScope.kt new file mode 100644 index 0000000..72ac6e2 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/VerifyScope.kt @@ -0,0 +1,48 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin + + +/** + * Verify multiple calls on mock + * Supports an easier to read style of + * + * ``` + * verify(mock) { + * 2 * { call() } + * } + * ``` + */ +inline fun verify(mock: T, block: VerifyScope.() -> Unit) { + VerifyScope(mock).block() +} + +class VerifyScope(val mock: T) { + + operator inline fun Int.times(call: T.() -> Unit) { + verify(mock, org.mockito.kotlin.times(this)).call() + } +} \ No newline at end of file diff --git a/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/internal/CreateInstance.kt b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/internal/CreateInstance.kt new file mode 100644 index 0000000..59ede91 --- /dev/null +++ b/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/internal/CreateInstance.kt @@ -0,0 +1,56 @@ +/* + * The MIT License + * + * Copyright (c) 2018 Niek Haarman + * Copyright (c) 2007 Mockito contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.mockito.kotlin.internal + +import kotlin.reflect.KClass +import java.lang.reflect.Array as JavaArray + +inline fun createInstance(): T { + return when (T::class) { + Boolean::class -> false as T + Byte::class -> 0.toByte() as T + Char::class -> 0.toChar() as T + Short::class -> 0.toShort() as T + Int::class -> 0 as T + Long::class -> 0L as T + Float::class -> 0f as T + Double::class -> 0.0 as T + else -> createInstance(T::class) + } +} + +fun createInstance(kClass: KClass): T { + return castNull() +} + +/** + * Uses a quirk in the bytecode generated by Kotlin + * to cast [null] to a non-null type. + * + * See https://youtrack.jetbrains.com/issue/KT-8135. + */ +@Suppress("UNCHECKED_CAST") +private fun castNull(): T = null as T diff --git a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt index 86d35b2..5ca6eb6 100644 --- a/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt +++ b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt @@ -3,12 +3,12 @@ package test import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.junit.Test +import org.mockito.kotlin.* class CoroutinesTest { diff --git a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt index 10ddb5e..703e750 100644 --- a/tests/src/test/kotlin/test/ArgumentCaptorTest.kt +++ b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt @@ -2,8 +2,8 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockitokotlin2.* import org.junit.Test +import org.mockito.kotlin.* import java.util.* class ArgumentCaptorTest : TestBase() { diff --git a/tests/src/test/kotlin/test/BDDMockitoTest.kt b/tests/src/test/kotlin/test/BDDMockitoTest.kt index 3d43ac4..0472163 100644 --- a/tests/src/test/kotlin/test/BDDMockitoTest.kt +++ b/tests/src/test/kotlin/test/BDDMockitoTest.kt @@ -1,8 +1,8 @@ package test import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* import org.junit.Test +import org.mockito.kotlin.* import org.mockito.stubbing.Answer class BDDMockitoTest { @@ -126,6 +126,6 @@ class BDDMockitoTest { mock.stringResult() /* Then */ - then(mock).should().stringResult() + org.mockito.kotlin.then(mock).should().stringResult() } } diff --git a/tests/src/test/kotlin/test/EqTest.kt b/tests/src/test/kotlin/test/EqTest.kt index fe993c6..2f64c09 100644 --- a/tests/src/test/kotlin/test/EqTest.kt +++ b/tests/src/test/kotlin/test/EqTest.kt @@ -26,8 +26,8 @@ package test */ import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.eq -import com.nhaarman.mockitokotlin2.mock +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock import org.junit.After import org.junit.Before import org.junit.Test diff --git a/tests/src/test/kotlin/test/MatchersTest.kt b/tests/src/test/kotlin/test/MatchersTest.kt index 4aea90e..afed69f 100644 --- a/tests/src/test/kotlin/test/MatchersTest.kt +++ b/tests/src/test/kotlin/test/MatchersTest.kt @@ -2,13 +2,14 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockitokotlin2.* import org.junit.Test import org.mockito.ArgumentMatcher import org.mockito.internal.matchers.VarargMatcher import org.mockito.invocation.InvocationOnMock +import org.mockito.kotlin.* import org.mockito.stubbing.Answer import java.io.IOException +import kotlin.check class MatchersTest : TestBase() { diff --git a/tests/src/test/kotlin/test/MockingTest.kt b/tests/src/test/kotlin/test/MockingTest.kt index 0bb19ce..43e6413 100644 --- a/tests/src/test/kotlin/test/MockingTest.kt +++ b/tests/src/test/kotlin/test/MockingTest.kt @@ -3,12 +3,12 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail -import com.nhaarman.mockitokotlin2.UseConstructor.Companion.parameterless -import com.nhaarman.mockitokotlin2.UseConstructor.Companion.withArguments -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import org.mockito.kotlin.UseConstructor.Companion.parameterless +import org.mockito.kotlin.UseConstructor.Companion.withArguments +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever import org.junit.Test import org.mockito.Mockito import org.mockito.exceptions.verification.WantedButNotInvoked diff --git a/tests/src/test/kotlin/test/OngoingStubbingTest.kt b/tests/src/test/kotlin/test/OngoingStubbingTest.kt index 64ce9b3..3c9268e 100644 --- a/tests/src/test/kotlin/test/OngoingStubbingTest.kt +++ b/tests/src/test/kotlin/test/OngoingStubbingTest.kt @@ -3,12 +3,13 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage import com.nhaarman.expect.fail -import com.nhaarman.mockitokotlin2.* import org.junit.Assume.assumeFalse import org.junit.Test import org.mockito.Mockito import org.mockito.exceptions.misusing.UnfinishedStubbingException +import org.mockito.kotlin.* import org.mockito.stubbing.Answer +import kotlin.check class OngoingStubbingTest : TestBase() { diff --git a/tests/src/test/kotlin/test/SpyTest.kt b/tests/src/test/kotlin/test/SpyTest.kt index c2f2bca..500faee 100644 --- a/tests/src/test/kotlin/test/SpyTest.kt +++ b/tests/src/test/kotlin/test/SpyTest.kt @@ -26,10 +26,10 @@ package test */ import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* import org.junit.After import org.junit.Test import org.mockito.Mockito +import org.mockito.kotlin.* import java.util.* class SpyTest : TestBase() { diff --git a/tests/src/test/kotlin/test/StubberTest.kt b/tests/src/test/kotlin/test/StubberTest.kt index 0e7ce65..eb6e28c 100644 --- a/tests/src/test/kotlin/test/StubberTest.kt +++ b/tests/src/test/kotlin/test/StubberTest.kt @@ -2,8 +2,8 @@ package test import com.nhaarman.expect.expect import com.nhaarman.expect.expectErrorWithMessage -import com.nhaarman.mockitokotlin2.* import org.junit.Test +import org.mockito.kotlin.* class StubberTest : TestBase() { diff --git a/tests/src/test/kotlin/test/VerificationTest.kt b/tests/src/test/kotlin/test/VerificationTest.kt index 1858dec..f2f92fd 100644 --- a/tests/src/test/kotlin/test/VerificationTest.kt +++ b/tests/src/test/kotlin/test/VerificationTest.kt @@ -1,9 +1,10 @@ package test import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* import org.junit.Test import org.mockito.exceptions.base.MockitoAssertionError +import org.mockito.kotlin.* +import org.mockito.kotlin.verify class VerificationTest : TestBase() { diff --git a/tests/src/test/kotlin/test/VerifyTest.kt b/tests/src/test/kotlin/test/VerifyTest.kt index 85915f3..0a93832 100644 --- a/tests/src/test/kotlin/test/VerifyTest.kt +++ b/tests/src/test/kotlin/test/VerifyTest.kt @@ -1,8 +1,8 @@ package test -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify import org.junit.Test import org.mockito.exceptions.verification.TooLittleActualInvocations import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent diff --git a/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt b/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt index b214fcc..6d160c7 100644 --- a/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt +++ b/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt @@ -1,7 +1,7 @@ package test.createinstance import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.internal.createInstance +import org.mockito.kotlin.internal.createInstance import org.junit.Test import test.TestBase diff --git a/tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt b/tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt index 6c69ccb..b03d77e 100644 --- a/tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt +++ b/tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt @@ -23,10 +23,10 @@ */ import com.nhaarman.expect.expect -import com.nhaarman.mockitokotlin2.* import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test +import org.mockito.kotlin.* import test.mockMakerInlineEnabled import java.io.IOException import java.math.BigInteger -- cgit v1.2.3 From c11c7378384884e0327d4cedda923e44afb2c483 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Sat, 20 Mar 2021 19:30:02 -0500 Subject: Enabled automated releases --- build.gradle | 21 +++++++++++++++++---- version.properties | 3 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 8d74f9b..39b0f65 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,29 @@ +buildscript { + repositories { + mavenLocal() // for local testing + maven { url "https://plugins.gradle.org/m2/" } + } + dependencies { + classpath "org.shipkit:shipkit-changelog:1.+" + classpath "org.shipkit:shipkit-auto-version:1.+" + } +} + plugins { - id "org.shipkit.shipkit-auto-version" version "1.1.1" - id "org.shipkit.shipkit-changelog" version "1.1.10" - id "org.shipkit.shipkit-github-release" version "1.1.10" id "io.github.gradle-nexus.publish-plugin" version "1.0.0" } -//TODO: change java packages to "org.mockito.kotlin" +apply plugin: "org.shipkit.shipkit-auto-version" +apply plugin: "org.shipkit.shipkit-changelog" +apply plugin: "org.shipkit.shipkit-github-release" + group = 'org.mockito.kotlin' tasks.named("generateChangelog") { previousRevision = project.ext.'shipkit-auto-version.previous-tag' githubToken = System.getenv("GITHUB_TOKEN") repository = "mockito/mockito-kotlin" + releaseTag = project.version } tasks.named("githubRelease") { @@ -21,6 +33,7 @@ tasks.named("githubRelease") { changelog = genTask.outputFile githubToken = System.getenv("GITHUB_TOKEN") newTagRevision = System.getenv("GITHUB_SHA") + releaseTag = project.version } nexusPublishing { diff --git a/version.properties b/version.properties index 8285f56..708e7ad 100644 --- a/version.properties +++ b/version.properties @@ -1,3 +1,4 @@ # Version of the produced binaries. # The version is inferred by shipkit-auto-version Gradle plugin (https://github.com/shipkit/shipkit-auto-version) -version=2.3.0 +version=2.2.* +tagPrefix= \ No newline at end of file -- cgit v1.2.3 From ca7c17e5013b1777cb3c51dd69d99de8bc163412 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Tue, 16 Mar 2021 10:09:52 -0500 Subject: Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3dd06af..da82e7d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,7 @@ jobs: java-version: 8 - name: Build and release - run: ./gradlew githubRelease publishToSonatype # closeAndReleaseStagingRepository + run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}} -- cgit v1.2.3 From 6c7aeaf4e362b75a7a206e98eb051b98c2dc2933 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Sat, 20 Mar 2021 19:30:02 -0500 Subject: Enabled automated releases --- build.gradle | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 39b0f65..4ee6ca3 100644 --- a/build.gradle +++ b/build.gradle @@ -34,12 +34,16 @@ tasks.named("githubRelease") { githubToken = System.getenv("GITHUB_TOKEN") newTagRevision = System.getenv("GITHUB_SHA") releaseTag = project.version + releaseName = project.version } nexusPublishing { repositories { if (System.getenv("NEXUS_TOKEN_PWD")) { - sonatype { + sonatype { // Publishing to: https://s01.oss.sonatype.org (faster instance) + nexusUrl = uri("https://s01.oss.sonatype.org/service/local/") + snapshotRepositoryUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") + username = System.getenv("NEXUS_TOKEN_USER") password = System.getenv("NEXUS_TOKEN_PWD") } -- cgit v1.2.3 From 15db36b278e5aebf035716f3b14552e28fb0aaf4 Mon Sep 17 00:00:00 2001 From: Szczepan Faber Date: Mon, 22 Mar 2021 09:54:30 -0500 Subject: Fixed group assignment --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4ee6ca3..3e55fa8 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,9 @@ apply plugin: "org.shipkit.shipkit-auto-version" apply plugin: "org.shipkit.shipkit-changelog" apply plugin: "org.shipkit.shipkit-github-release" -group = 'org.mockito.kotlin' +allprojects { + group = 'org.mockito.kotlin' +} tasks.named("generateChangelog") { previousRevision = project.ext.'shipkit-auto-version.previous-tag' -- cgit v1.2.3 From bd79b5e393b91cd47f9e4a5b9a874182004d2d1c Mon Sep 17 00:00:00 2001 From: Mario Rezende Date: Mon, 22 Mar 2021 17:26:34 -0300 Subject: Update groupId in installation instructions (#414) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d43db7..b9677c8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Mockito-Kotlin is available on Maven Central and JCenter. For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` with the latest version: ```groovy -testImplementation "org.mockito:mockito-kotlin:x.x.x" +testImplementation "org.mockito.kotlin:mockito-kotlin:x.x.x" ``` ## Example -- cgit v1.2.3 From 17e2c057843b84944a455f186006840884969e5a Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Tue, 23 Mar 2021 12:10:56 +0100 Subject: Fix artifact groupId in Maven Central badge (#416) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9677c8..7076550 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Mockito-Kotlin -[ ![Download](https://maven-badges.herokuapp.com/maven-central/org.mockito/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/org.mockito/mockito-kotlin) +[ ![Download](https://maven-badges.herokuapp.com/maven-central/org.mockito/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/org.mockito.kotlin/mockito-kotlin) A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. -- cgit v1.2.3 From bcbea6a9c9689742e82c9c511ad1cb06fcdf842f Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Tue, 23 Mar 2021 12:12:19 +0100 Subject: Add all IntelliJ files to gitignore (#415) --- .gitignore | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index f9e1291..4b102ff 100644 --- a/.gitignore +++ b/.gitignore @@ -5,20 +5,9 @@ repo # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar -*.iml -.idea/caches/* -.idea/compiler.xml -.idea/encodings.xml -.idea/gradle.xml -.idea/kotlinc.xml -.idea/libraries/* -.idea/misc.xml -.idea/modules.xml -.idea/runConfigurations.xml -.idea/shelf -.idea/uiDesigner.xml -.idea/vcs.xml -.idea/workspace.xml +# intelliJ +.idea/ +*.iml *.orig -- cgit v1.2.3 From 37bbae48634d879640a754a1b122db99f0b00478 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Tue, 23 Mar 2021 13:38:18 +0100 Subject: Retrieve correct version number in Maven Central badge (#419) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7076550..abac3de 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Mockito-Kotlin -[ ![Download](https://maven-badges.herokuapp.com/maven-central/org.mockito/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/org.mockito.kotlin/mockito-kotlin) +[ ![Download](https://maven-badges.herokuapp.com/maven-central/org.mockito.kotlin/mockito-kotlin/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/org.mockito.kotlin/mockito-kotlin) A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin. -- cgit v1.2.3 From 33001215356f8e25e6c5566ac5cd5db6e87e446d Mon Sep 17 00:00:00 2001 From: Roma Modi Date: Tue, 13 Jun 2023 15:19:47 -0700 Subject: Add Android.bp and metadata files Test: treehugger Change-Id: Id3484652f3314110e3afb1a2d7bee41a2a44271f --- Android.bp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ METADATA | 14 +++++++++++++ MODULE_LICENSE_MIT | 0 OWNERS | 2 ++ update_source.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 Android.bp create mode 100644 METADATA create mode 100644 MODULE_LICENSE_MIT create mode 100644 OWNERS create mode 100644 update_source.sh diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000..9c7e088 --- /dev/null +++ b/Android.bp @@ -0,0 +1,58 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// + +package { + default_applicable_licenses: ["external_mockito_kotlin_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "external_mockito_kotlin_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "SPDX-license-identifier-MIT", + ], + license_text: [ + "LICENSE", + ], +} + +java_library_static { + // TODO (b/289573112): mockito-kotlin name is already in use by a WearOS prebuilt. + // Rename to mockito-kotlin once that prebuilt is removed. + name: "mockito-kotlin2", + hostdex: true, + srcs: ["mockito-kotlin/src/main/**/*.kt"], + + static_libs: ["mockito", "kotlinx_coroutines"], + + sdk_version: "module_current" +} + diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..22433c5 --- /dev/null +++ b/METADATA @@ -0,0 +1,14 @@ +name: "mockito-kotlin" +description: + "Mockito for Kotlin" + +third_party { + url { + type: GIT + value: "https://github.com/mockito/mockito-kotlin" + } + version: “2.2.11” + last_upgrade_date { year: 2023 month: 6 day: 13 } + license_type: NOTICE +} + diff --git a/MODULE_LICENSE_MIT b/MODULE_LICENSE_MIT new file mode 100644 index 0000000..e69de29 diff --git a/OWNERS b/OWNERS new file mode 100644 index 0000000..88f0700 --- /dev/null +++ b/OWNERS @@ -0,0 +1,2 @@ +romam@google.com +farivar@google.com diff --git a/update_source.sh b/update_source.sh new file mode 100644 index 0000000..52848d2 --- /dev/null +++ b/update_source.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# +# Copyright 2023 The Android Open Source Project. +# +# Retrieves the current mockito-kotlin source code into the current directory + +# Force stop on first error. +set -e + +if [ $# -ne 1 ]; then + echo "$0 " >&2 + exit 1; +fi + +if [ -z "$ANDROID_BUILD_TOP" ]; then + echo "Missing environment variables. Did you run build/envsetup.sh and lunch?" >&2 + exit 1 +fi + +VERSION=${1} + +SOURCE="git://github.com/mockito/mockito-kotlin.git" +INCLUDE=" + LICENSE + mockito-kotlin/src/main + " + +working_dir="$(mktemp -d)" +trap "echo \"Removing temporary directory\"; rm -rf $working_dir" EXIT + +echo "Fetching mockito-kotlin source into $working_dir" +git clone $SOURCE $working_dir/source +(cd $working_dir/source; git checkout $VERSION) + +for include in ${INCLUDE}; do + echo "Updating $include" + rm -rf $include + mkdir -p $(dirname $include) + cp -R $working_dir/source/$include $include +done; + +echo "Done" + +# Update the version. +perl -pi -e "s|^Version: .*$|Version: ${VERSION}|" "README.version" + +# Remove any documentation about local modifications. +mv README.version README.tmp +grep -B 100 "Local Modifications" README.tmp > README.version +echo " None" >> README.version +rm README.tmp + +echo "Done" -- cgit v1.2.3 From 9674303d2aa0c19e90ef775428ec416b231451d1 Mon Sep 17 00:00:00 2001 From: Sadaf Ebrahimi Date: Thu, 6 Jul 2023 17:08:06 +0000 Subject: Fix typo in METADATA Test: TreeHugger Change-Id: I89b7cf048a92eb5a8a83364c4158054a9d6351ab --- METADATA | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/METADATA b/METADATA index 22433c5..d7158a6 100644 --- a/METADATA +++ b/METADATA @@ -7,7 +7,7 @@ third_party { type: GIT value: "https://github.com/mockito/mockito-kotlin" } - version: “2.2.11” + version: "2.2.11" last_upgrade_date { year: 2023 month: 6 day: 13 } license_type: NOTICE } -- cgit v1.2.3