aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagdi <magdi@google.com>2023-10-27 17:33:13 +0000
committerMagdi <magdi@google.com>2023-10-27 19:09:46 +0000
commit97b4dba3417641b6ff7e68082483e78cfe1e76c6 (patch)
tree092f92003fb17c67736c9317996d8fcf127d1aa4
parent7d0540cff49cd6026c91c17a16bb2fbd16f0c9b4 (diff)
parentb0a025998405b7af4a64dd04ffdf6630e678658f (diff)
downloadmockito-kotlin-97b4dba3417641b6ff7e68082483e78cfe1e76c6.tar.gz
Merge remote-tracking branch 'goog/mirror-aosp-main' intoaml_wif_341610000aml_wif_341510000aml_wif_341410080aml_wif_341310010aml_uwb_341513070aml_uwb_341511050aml_uwb_341310300aml_uwb_341310030aml_tz5_341510010aml_tet_341610020aml_tet_341511010aml_tet_341411060aml_tet_341310230aml_sta_341615000aml_sta_341511040aml_sta_341410000aml_sta_341311010aml_sdk_341510000aml_sdk_341410000aml_sch_341510000aml_res_341510000aml_res_341410010aml_res_341311030aml_per_341614000aml_per_341510010aml_per_341410020aml_per_341311000aml_odp_341610000aml_neu_341510000aml_net_341610030aml_net_341510050aml_net_341510000aml_net_341411030aml_net_341311010aml_net_341310020aml_ips_341611000aml_ips_341510000aml_ext_341620040aml_ext_341518010aml_ext_341414010aml_ext_341317010aml_con_341614000aml_con_341511080aml_con_341410300aml_con_341310090aml_cfg_341510000aml_cbr_341610000aml_cbr_341510010aml_cbr_341410010aml_cbr_341311010aml_ase_341510000aml_ase_341410000aml_ase_341310010aml_art_341615020aml_art_341514450aml_art_341514410aml_art_341411300aml_art_341311100aml_ads_341615050aml_ads_341517040aml_ads_341413000aml_ads_341316030aml_adb_341520010aml_adb_341517070aml_adb_340912530android14-mainline-wifi-releaseandroid14-mainline-uwb-releaseandroid14-mainline-tethering-releaseandroid14-mainline-sdkext-releaseandroid14-mainline-resolv-releaseandroid14-mainline-permission-releaseandroid14-mainline-os-statsd-releaseandroid14-mainline-networking-releaseandroid14-mainline-extservices-releaseandroid14-mainline-conscrypt-releaseandroid14-mainline-cellbroadcast-releaseandroid14-mainline-art-releaseandroid14-mainline-appsearch-releaseandroid14-mainline-adservices-releaseaml_tz5_341510010
'udc-mainline-prod' Bug: 308181344 Test: TH Change-Id: Iff81d3b769a149fc25a8e0ab925f2ab9dfa6f601
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md4
-rw-r--r--.github/workflows/ci.yml106
-rw-r--r--.gitignore13
-rw-r--r--.idea/codeStyles/Project.xml276
-rw-r--r--.idea/codeStyles/codeStyleConfig.xml5
-rw-r--r--.idea/copyright/MIT.xml6
-rw-r--r--.idea/copyright/profiles_settings.xml7
-rw-r--r--.idea/inspectionProfiles/Project_Default.xml6
-rw-r--r--Android.bp58
-rw-r--r--LICENSE22
-rw-r--r--METADATA14
-rw-r--r--MODULE_LICENSE_MIT0
-rw-r--r--OWNERS2
-rw-r--r--README.md72
-rw-r--r--RELEASING.md3
-rw-r--r--build.gradle54
-rw-r--r--gradle.properties1
-rw-r--r--gradle/publishing.gradle69
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin0 -> 59203 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties5
-rwxr-xr-xgradlew185
-rw-r--r--gradlew.bat89
-rw-r--r--mockito-kotlin/build.gradle49
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt212
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/BDDMockito.kt81
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KStubbing.kt84
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Matchers.kt139
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mocking.kt211
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mockito.kt41
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/MockitoKotlinException.kt28
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/OngoingStubbing.kt126
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Spying.kt62
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Stubber.kt65
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Verification.kt263
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/VerifyScope.kt48
-rw-r--r--mockito-kotlin/src/main/kotlin/org/mockito/kotlin/internal/CreateInstance.kt56
-rw-r--r--mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt176
-rwxr-xr-xops/mockMakerInline.sh11
-rw-r--r--ops/org.mockito.plugins.MockMaker1
-rw-r--r--settings.gradle2
-rw-r--r--tests/README.md7
-rw-r--r--tests/build.gradle29
-rw-r--r--tests/src/test/kotlin/test/ArgumentCaptorTest.kt229
-rw-r--r--tests/src/test/kotlin/test/BDDMockitoTest.kt131
-rw-r--r--tests/src/test/kotlin/test/Classes.kt108
-rw-r--r--tests/src/test/kotlin/test/EqTest.kt101
-rw-r--r--tests/src/test/kotlin/test/MatchersTest.kt334
-rw-r--r--tests/src/test/kotlin/test/MockMaker.kt10
-rw-r--r--tests/src/test/kotlin/test/MockingTest.kt357
-rw-r--r--tests/src/test/kotlin/test/OngoingStubbingTest.kt340
-rw-r--r--tests/src/test/kotlin/test/SpyTest.kt141
-rw-r--r--tests/src/test/kotlin/test/StubberTest.kt103
-rw-r--r--tests/src/test/kotlin/test/TestBase.kt11
-rw-r--r--tests/src/test/kotlin/test/VerificationTest.kt115
-rw-r--r--tests/src/test/kotlin/test/VerifyTest.kt96
-rw-r--r--tests/src/test/kotlin/test/createinstance/NullCasterTest.kt31
-rw-r--r--tests/src/test/kotlin/test/inline/UsingMockMakerInlineTest.kt116
-rw-r--r--update_source.sh53
-rw-r--r--version.properties4
59 files changed, 4968 insertions, 0 deletions
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..ee9389c
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,4 @@
+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).
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..da82e7d
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,106 @@
+#
+# 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.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:
+
+ - 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
+ 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 release
+ run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository
+ env:
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
+ 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/.gitignore b/.gitignore
new file mode 100644
index 0000000..4b102ff
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+.gradle
+build/
+out/
+repo
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# intelliJ
+.idea/
+*.iml
+
+*.orig
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 @@
+<component name="ProjectCodeStyleConfiguration">
+ <code_scheme name="Project" version="173">
+ <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
+ <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
+ <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
+ <value />
+ </option>
+ <option name="IMPORT_LAYOUT_TABLE">
+ <value>
+ <package name="android" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="com" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="junit" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="net" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="org" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="java" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="javax" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="" withSubpackages="true" static="true" />
+ <emptyLine />
+ </value>
+ </option>
+ <option name="RIGHT_MARGIN" value="100" />
+ <AndroidXmlCodeStyleSettings>
+ <option name="USE_CUSTOM_SETTINGS" value="true" />
+ </AndroidXmlCodeStyleSettings>
+ <JavaCodeStyleSettings>
+ <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
+ <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
+ <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
+ <value />
+ </option>
+ <option name="IMPORT_LAYOUT_TABLE">
+ <value>
+ <package name="android" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="com" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="junit" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="net" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="org" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="java" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="javax" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="" withSubpackages="true" static="false" />
+ <emptyLine />
+ <package name="" withSubpackages="true" static="true" />
+ <emptyLine />
+ </value>
+ </option>
+ </JavaCodeStyleSettings>
+ <JetCodeStyleSettings>
+ <option name="IMPORT_NESTED_CLASSES" value="true" />
+ <option name="CONTINUATION_INDENT_IN_PARAMETER_LISTS" value="false" />
+ <option name="CONTINUATION_INDENT_FOR_EXPRESSION_BODIES" value="false" />
+ <option name="CONTINUATION_INDENT_FOR_CHAINED_CALLS" value="false" />
+ </JetCodeStyleSettings>
+ <Objective-C-extensions>
+ <file>
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
+ </file>
+ <class>
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
+ <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
+ </class>
+ <extensions>
+ <pair source="cpp" header="h" fileNamingConvention="NONE" />
+ <pair source="c" header="h" fileNamingConvention="NONE" />
+ </extensions>
+ </Objective-C-extensions>
+ <XML>
+ <option name="XML_KEEP_LINE_BREAKS" value="false" />
+ <option name="XML_ALIGN_ATTRIBUTES" value="false" />
+ <option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
+ <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+ </XML>
+ <codeStyleSettings language="JAVA">
+ <indentOptions>
+ <option name="CONTINUATION_INDENT_SIZE" value="6" />
+ </indentOptions>
+ </codeStyleSettings>
+ <codeStyleSettings language="XML">
+ <option name="FORCE_REARRANGE_MODE" value="1" />
+ <indentOptions>
+ <option name="CONTINUATION_INDENT_SIZE" value="4" />
+ </indentOptions>
+ <arrangement>
+ <rules>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>xmlns:android</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>xmlns:.*</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:id</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:name</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>name</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>style</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:layout_width</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:layout_height</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:layout_.*</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:width</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:height</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*</NAME>
+ <XML_NAMESPACE>.*</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ </rules>
+ </arrangement>
+ </codeStyleSettings>
+ <codeStyleSettings language="kotlin">
+ <option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
+ <option name="CALL_PARAMETERS_WRAP" value="5" />
+ <option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
+ <option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
+ <option name="METHOD_PARAMETERS_WRAP" value="5" />
+ <option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
+ <option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
+ <option name="EXTENDS_LIST_WRAP" value="1" />
+ <indentOptions>
+ <option name="CONTINUATION_INDENT_SIZE" value="6" />
+ </indentOptions>
+ </codeStyleSettings>
+ </code_scheme>
+</component> \ 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 @@
+<component name="ProjectCodeStyleConfiguration">
+ <state>
+ <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+ </state>
+</component> \ 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 @@
+<component name="CopyrightManager">
+ <copyright>
+ <option name="myName" value="MIT" />
+ <option name="notice" value="The MIT License&#10;&#10;Copyright (c) 2018 Niek Haarman&#10;Copyright (c) 2007 Mockito contributors&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE." />
+ </copyright>
+</component> \ 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 @@
+<component name="CopyrightManager">
+ <settings>
+ <module2copyright>
+ <element module="Production" copyright="MIT" />
+ </module2copyright>
+ </settings>
+</component> \ No newline at end of file
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 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="Project Default" />
+ <inspection_tool class="CanBeParameter" enabled="false" level="WARNING" enabled_by_default="false" />
+ </profile>
+</component> \ No newline at end of file
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/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/METADATA b/METADATA
new file mode 100644
index 0000000..d7158a6
--- /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
--- /dev/null
+++ b/MODULE_LICENSE_MIT
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/README.md b/README.md
new file mode 100644
index 0000000..abac3de
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+# 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.
+
+## Install
+
+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.kotlin:mockito-kotlin:x.x.x"
+```
+
+## Example
+
+A test using Mockito-Kotlin typically looks like the following:
+
+```kotlin
+@Test
+fun doAction_doesSomething(){
+ /* Given */
+ val mock = mock<MyClass> {
+ on { getText() } doReturn "text"
+ }
+ val classUnderTest = ClassUnderTest(mock)
+
+ /* When */
+ classUnderTest.doAction()
+
+ /* Then */
+ verify(mock).doSomething(any())
+}
+```
+
+For more info and samples, see the [Wiki](https://github.com/mockito/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.
+
+### 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`.
diff --git a/RELEASING.md b/RELEASING.md
new file mode 100644
index 0000000..3f0140c
--- /dev/null
+++ b/RELEASING.md
@@ -0,0 +1,3 @@
+# Releasing
+
+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
new file mode 100644
index 0000000..3e55fa8
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,54 @@
+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 "io.github.gradle-nexus.publish-plugin" version "1.0.0"
+}
+
+apply plugin: "org.shipkit.shipkit-auto-version"
+apply plugin: "org.shipkit.shipkit-changelog"
+apply plugin: "org.shipkit.shipkit-github-release"
+
+allprojects {
+ 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") {
+ def genTask = tasks.named("generateChangelog").get()
+ dependsOn genTask
+ repository = genTask.repository
+ changelog = genTask.outputFile
+ 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 { // 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")
+ }
+ }
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..5d8bda0
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1 @@
+isRelease=false
diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle
new file mode 100644
index 0000000..6bb5f1a
--- /dev/null
+++ b/gradle/publishing.gradle
@@ -0,0 +1,69 @@
+apply plugin: 'maven-publish'
+
+task javadocJar(type: Jar, dependsOn: javadoc) {
+ classifier = 'javadoc'
+ from 'build/javadoc'
+}
+
+task sourceJar(type: Jar) {
+ from sourceSets.main.allSource
+}
+
+publishing {
+ publications {
+ javaLibrary(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" } }
+}
+
+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')
+
+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/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..28ff446
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+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
new file mode 100755
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/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
+##
+##############################################################################
+
+# 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='"-Xmx64m" "-Xms64m"'
+
+# 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
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+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
+ # 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" -a "$nonstop" = "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 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
+ 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=`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" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+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"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..ac1b06f
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@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
+@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 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="-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 execute
+
+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 execute
+
+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
+
+: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 %*
+
+: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..6c726db
--- /dev/null
+++ b/mockito-kotlin/build.gradle
@@ -0,0 +1,49 @@
+apply plugin: 'kotlin'
+apply from: '../gradle/publishing.gradle'
+apply plugin: 'org.jetbrains.dokka'
+
+buildscript {
+ ext.kotlin_version = "1.3.50"
+
+ repositories {
+ mavenCentral()
+ jcenter()
+ }
+
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17"
+ }
+}
+
+repositories {
+ mavenCentral()
+ jcenter()
+}
+
+dependencies {
+ compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
+
+ compile "org.mockito:mockito-core:2.23.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:1.0.0'
+
+ testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.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
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 <reified T : Any> argumentCaptor(): KArgumentCaptor<T> {
+ return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
+}
+
+/**
+ * Creates 2 [KArgumentCaptor]s for given types.
+ */
+inline fun <reified A : Any, reified B : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class
+): Pair<KArgumentCaptor<A>, KArgumentCaptor<B>> {
+ return Pair(
+ KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
+ KArgumentCaptor(ArgumentCaptor.forClass(b.java), b)
+ )
+}
+
+/**
+ * Creates 3 [KArgumentCaptor]s for given types.
+ */
+inline fun <reified A : Any, reified B : Any, reified C : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class,
+ c: KClass<C> = C::class
+): Triple<KArgumentCaptor<A>, KArgumentCaptor<B>, KArgumentCaptor<C>> {
+ return Triple(
+ KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
+ KArgumentCaptor(ArgumentCaptor.forClass(b.java), b),
+ KArgumentCaptor(ArgumentCaptor.forClass(c.java), c)
+ )
+}
+
+class ArgumentCaptorHolder4<out A, out B, out C, out D>(
+ 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<out A, out B, out C, out D, out E>(
+ 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 <reified A : Any, reified B : Any, reified C : Any, reified D : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class,
+ c: KClass<C> = C::class,
+ d: KClass<D> = D::class
+): ArgumentCaptorHolder4<KArgumentCaptor<A>, KArgumentCaptor<B>, KArgumentCaptor<C>, KArgumentCaptor<D>> {
+ 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 <reified A : Any, reified B : Any, reified C : Any, reified D : Any, reified E : Any> argumentCaptor(
+ a: KClass<A> = A::class,
+ b: KClass<B> = B::class,
+ c: KClass<C> = C::class,
+ d: KClass<D> = D::class,
+ e: KClass<E> = E::class
+): ArgumentCaptorHolder5<KArgumentCaptor<A>, KArgumentCaptor<B>, KArgumentCaptor<C>, KArgumentCaptor<D>, KArgumentCaptor<E>> {
+ 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 <reified T : Any> argumentCaptor(f: KArgumentCaptor<T>.() -> Unit): KArgumentCaptor<T> {
+ return argumentCaptor<T>().apply(f)
+}
+
+/**
+ * Creates a [KArgumentCaptor] for given nullable type.
+ */
+inline fun <reified T : Any> nullableArgumentCaptor(): KArgumentCaptor<T?> {
+ 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 <reified T : Any> nullableArgumentCaptor(f: KArgumentCaptor<T?>.() -> Unit): KArgumentCaptor<T?> {
+ return nullableArgumentCaptor<T>().apply(f)
+}
+
+/**
+ * Alias for [ArgumentCaptor.capture].
+ */
+inline fun <reified T : Any> capture(captor: ArgumentCaptor<T>): T {
+ return captor.capture() ?: createInstance()
+}
+
+class KArgumentCaptor<out T : Any?>(
+ private val captor: ArgumentCaptor<T>,
+ 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<T>
+ get() = captor.allValues
+
+ @Suppress("UNCHECKED_CAST")
+ fun capture(): T {
+ return captor.capture() ?: createInstance(tClass) as T
+ }
+}
+
+val <T> ArgumentCaptor<T>.firstValue: T
+ get() = allValues[0]
+
+val <T> ArgumentCaptor<T>.secondValue: T
+ get() = allValues[1]
+
+val <T> ArgumentCaptor<T>.thirdValue: T
+ get() = allValues[2]
+
+val <T> ArgumentCaptor<T>.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 <T> given(methodCall: T): BDDMockito.BDDMyOngoingStubbing<T> {
+ return BDDMockito.given(methodCall)
+}
+
+/**
+ * Alias for [BDDMockito.given] with a lambda.
+ */
+fun <T> given(methodCall: () -> T): BDDMyOngoingStubbing<T> {
+ return given(methodCall())
+}
+
+/**
+ * Alias for [BDDMockito.then].
+ */
+fun <T> then(mock: T): BDDMockito.Then<T> {
+ return BDDMockito.then(mock)
+}
+
+/**
+ * Alias for [BDDMyOngoingStubbing.will]
+ * */
+infix fun <T> BDDMyOngoingStubbing<T>.will(value: Answer<T>): BDDMockito.BDDMyOngoingStubbing<T> {
+ return will(value)
+}
+
+/**
+ * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a lambda.
+ */
+infix fun <T> BDDMyOngoingStubbing<T>.willAnswer(value: (InvocationOnMock) -> T?): BDDMockito.BDDMyOngoingStubbing<T> {
+ return willAnswer { value(it) }
+}
+
+/**
+ * Alias for [BBDMyOngoingStubbing.willReturn].
+ */
+infix fun <T> BDDMyOngoingStubbing<T>.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing<T> {
+ return willReturn(value())
+}
+
+/**
+ * Alias for [BBDMyOngoingStubbing.willThrow].
+ */
+infix fun <T> BDDMyOngoingStubbing<T>.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing<T> {
+ 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 <T> stubbing(
+ mock: T,
+ stubbing: KStubbing<T>.(T) -> Unit
+) {
+ KStubbing(mock).stubbing(mock)
+}
+
+inline fun <T : Any> T.stub(stubbing: KStubbing<T>.(T) -> Unit): T {
+ return apply { KStubbing(this).stubbing(this) }
+}
+
+class KStubbing<out T>(val mock: T) {
+
+ fun <R> on(methodCall: R): OngoingStubbing<R> = Mockito.`when`(methodCall)
+
+ fun <R : Any> onGeneric(methodCall: T.() -> R?, c: KClass<R>): OngoingStubbing<R> {
+ 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 <reified R : Any> onGeneric(noinline methodCall: T.() -> R?): OngoingStubbing<R> {
+ return onGeneric(methodCall, R::class)
+ }
+
+ fun <R> on(methodCall: T.() -> R): OngoingStubbing<R> {
+ 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 <T : Any, R> KStubbing<T>.onBlocking(
+ m: suspend T.() -> R
+ ): OngoingStubbing<R> {
+ 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 <T> eq(value: T): T {
+ return Mockito.eq(value) ?: value
+}
+
+/** Object argument that is the same as the given value. */
+fun <T> same(value: T): T {
+ return Mockito.same(value) ?: value
+}
+
+/** Matches any object, excluding nulls. */
+inline fun <reified T : Any> any(): T {
+ return Mockito.any(T::class.java) ?: createInstance()
+}
+
+/** Matches anything, including nulls. */
+inline fun <reified T : Any> anyOrNull(): T {
+ return Mockito.any<T>() ?: createInstance()
+}
+
+/** Matches any vararg object, including nulls. */
+inline fun <reified T : Any> anyVararg(): T {
+ return Mockito.any<T>() ?: createInstance()
+}
+
+/** Matches any array of type T. */
+inline fun <reified T : Any?> anyArray(): Array<T> {
+ return Mockito.any(Array<T>::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 <reified T : Any> 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 <reified T : Any> argThat(matcher: ArgumentMatcher<T>): 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 <reified T : Any> 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 <reified T : Any> argWhere(noinline predicate: (T) -> Boolean): T {
+ return argThat(predicate)
+}
+
+/**
+ * Argument that implements the given class.
+ */
+inline fun <reified T : Any> isA(): T {
+ return Mockito.isA(T::class.java) ?: createInstance()
+}
+
+/**
+ * `null` argument.
+ */
+fun <T : Any> isNull(): T? = Mockito.isNull()
+
+/**
+ * Not `null` argument.
+ */
+fun <T : Any> isNotNull(): T? {
+ return Mockito.isNotNull()
+}
+
+/**
+ * Not `null` argument.
+ */
+fun <T : Any> 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 <reified T : Any> refEq(value: T, vararg excludeFields: String): T {
+ return Mockito.refEq<T>(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 <reified T : Any> mock(
+ extraInterfaces: Array<out KClass<out Any>>? = null,
+ name: String? = null,
+ spiedInstance: Any? = null,
+ defaultAnswer: Answer<Any>? = null,
+ serializable: Boolean = false,
+ serializableMode: SerializableMode? = null,
+ verboseLogging: Boolean = false,
+ invocationListeners: Array<InvocationListener>? = 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 <reified T : Any> mock(
+ extraInterfaces: Array<out KClass<out Any>>? = null,
+ name: String? = null,
+ spiedInstance: Any? = null,
+ defaultAnswer: Answer<Any>? = null,
+ serializable: Boolean = false,
+ serializableMode: SerializableMode? = null,
+ verboseLogging: Boolean = false,
+ invocationListeners: Array<InvocationListener>? = null,
+ stubOnly: Boolean = false,
+ @Incubating useConstructor: UseConstructor? = null,
+ @Incubating outerInstance: Any? = null,
+ @Incubating lenient: Boolean = false,
+ stubbing: KStubbing<T>.(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<out KClass<out Any>>? = null,
+ name: String? = null,
+ spiedInstance: Any? = null,
+ defaultAnswer: Answer<Any>? = null,
+ serializable: Boolean = false,
+ serializableMode: SerializableMode? = null,
+ verboseLogging: Boolean = false,
+ invocationListeners: Array<InvocationListener>? = 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<Any>) {
+
+ 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<T>(defaultAnswer = a)"),
+ level = ERROR
+)
+inline fun <reified T : Any> mock(a: Answer<Any>): T = mock(defaultAnswer = a)
+
+@Deprecated(
+ "Use mock() with optional arguments instead.",
+ ReplaceWith("mock<T>(name = s)"),
+ level = ERROR
+)
+inline fun <reified T : Any> mock(s: String): T = mock(name = s)
+
+@Suppress("DeprecatedCallableAddReplaceWith")
+@Deprecated("Use mock() with optional arguments instead.", level = ERROR)
+inline fun <reified T : Any> 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 <T> 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 <T> whenever(methodCall: T): OngoingStubbing<T> {
+ return Mockito.`when`(methodCall)!!
+}
+
+/**
+ * Sets a return value to be returned when the method is called.
+ *
+ * Alias for [OngoingStubbing.thenReturn].
+ */
+infix fun <T> OngoingStubbing<T>.doReturn(t: T): OngoingStubbing<T> {
+ return thenReturn(t)
+}
+
+/**
+ * Sets consecutive return values to be returned when the method is called.
+ *
+ * Alias for [OngoingStubbing.thenReturn].
+ */
+fun <T> OngoingStubbing<T>.doReturn(t: T, vararg ts: T): OngoingStubbing<T> {
+ return thenReturn(t, *ts)
+}
+
+/**
+ * Sets consecutive return values to be returned when the method is called.
+ */
+inline infix fun <reified T> OngoingStubbing<T>.doReturnConsecutively(ts: List<T>): OngoingStubbing<T> {
+ 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 <T> OngoingStubbing<T>.doThrow(t: Throwable): OngoingStubbing<T> {
+ return thenThrow(t)
+}
+
+/**
+ * Sets Throwable objects to be thrown when the method is called.
+ *
+ * Alias for [OngoingStubbing.doThrow].
+ */
+fun <T> OngoingStubbing<T>.doThrow(
+ t: Throwable,
+ vararg ts: Throwable
+): OngoingStubbing<T> {
+ return thenThrow(t, *ts)
+}
+
+/**
+ * Sets a Throwable type to be thrown when the method is called.
+ */
+infix fun <T> OngoingStubbing<T>.doThrow(t: KClass<out Throwable>): OngoingStubbing<T> {
+ return thenThrow(t.java)
+}
+
+/**
+ * Sets Throwable classes to be thrown when the method is called.
+ */
+fun <T> OngoingStubbing<T>.doThrow(
+ t: KClass<out Throwable>,
+ vararg ts: KClass<out Throwable>
+): OngoingStubbing<T> {
+ return thenThrow(t.java, *ts.map { it.java }.toTypedArray())
+}
+
+/**
+ * Sets a generic Answer for the method.
+ *
+ * Alias for [OngoingStubbing.thenAnswer].
+ */
+infix fun <T> OngoingStubbing<T>.doAnswer(answer: Answer<*>): OngoingStubbing<T> {
+ return thenAnswer(answer)
+}
+
+/**
+ * Sets a generic Answer for the method using a lambda.
+ */
+infix fun <T> OngoingStubbing<T>.doAnswer(answer: (InvocationOnMock) -> T?): OngoingStubbing<T> {
+ 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 <b>real</b> methods unless they are stubbed.
+ */
+inline fun <reified T : Any> spy(): T {
+ return Mockito.spy(T::class.java)!!
+}
+
+/**
+ * Creates a spy of the real object, allowing for immediate stubbing.
+ * The spy calls <b>real</b> methods unless they are stubbed.
+ */
+inline fun <reified T : Any> spy(stubbing: KStubbing<T>.(T) -> Unit): T {
+ return Mockito.spy(T::class.java)
+ .apply { KStubbing(this).stubbing(this) }!!
+}
+
+/**
+ * Creates a spy of the real object. The spy calls <b>real</b> methods unless they are stubbed.
+ */
+fun <T> spy(value: T): T {
+ return Mockito.spy(value)!!
+}
+
+/**
+ * Creates a spy of the real object, allowing for immediate stubbing.
+ * The spy calls <b>real</b> methods unless they are stubbed.
+ */
+inline fun <reified T> spy(value: T, stubbing: KStubbing<T>.(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 <T> 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<out Throwable>): Stubber {
+ return Mockito.doThrow(toBeThrown.java)!!
+}
+
+fun doThrow(vararg toBeThrown: Throwable): Stubber {
+ return Mockito.doThrow(*toBeThrown)!!
+}
+
+fun <T> 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 <b>happened once</b>.
+ *
+ * Alias for [Mockito.verify].
+ */
+fun <T> verify(mock: T): T {
+ return Mockito.verify(mock)!!
+}
+
+/**
+ * Verifies certain suspending behavior <b>happened once</b>.
+ *
+ * Warning: Only one method call can be verified in the function.
+ * Subsequent method calls are ignored!
+ */
+fun <T> 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 <T> 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 <T> 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 <T> 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 <T> 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<out Any> {
+ 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> T.inOrder(block: InOrderOnType<T>.() -> Any) {
+ block.invoke(InOrderOnType(this))
+}
+
+class InOrderOnType<T>(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 <reified T : Any> 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 <T> verify(mock: T, block: VerifyScope<T>.() -> Unit) {
+ VerifyScope(mock).block()
+}
+
+class VerifyScope<out T>(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 <reified T : Any> 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 <T : Any> createInstance(kClass: KClass<T>): 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 <T> 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
new file mode 100644
index 0000000..5ca6eb6
--- /dev/null
+++ b/mockito-kotlin/src/test/kotlin/test/CoroutinesTest.kt
@@ -0,0 +1,176 @@
+@file:Suppress("EXPERIMENTAL_FEATURE_WARNING")
+
+package test
+
+import com.nhaarman.expect.expect
+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 {
+
+ @Test
+ fun stubbingSuspending() {
+ /* Given */
+ val m = mock<SomeInterface> {
+ onBlocking { suspending() } doReturn 42
+ }
+
+ /* When */
+ val result = runBlocking { m.suspending() }
+
+ /* Then */
+ expect(result).toBe(42)
+ }
+
+ @Test
+ fun stubbingSuspending_usingSuspendingFunction() {
+ /* Given */
+ val m = mock<SomeInterface> {
+ 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<SomeInterface> {
+ onBlocking { suspending() } doReturn 42
+ }
+
+ /* When */
+ val result = m.suspending()
+
+ /* Then */
+ expect(result).toBe(42)
+ }
+
+ @Test
+ fun stubbingNonSuspending() {
+ /* Given */
+ val m = mock<SomeInterface> {
+ onBlocking { nonsuspending() } doReturn 42
+ }
+
+ /* When */
+ val result = m.nonsuspending()
+
+ /* Then */
+ expect(result).toBe(42)
+ }
+
+ @Test
+ fun stubbingNonSuspending_runBlocking() = runBlocking {
+ /* Given */
+ val m = mock<SomeInterface> {
+ 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<SomeInterface>()
+
+ /* When */
+ runBlocking { m.suspending() }
+
+ /* Then */
+ runBlocking { verify(m).suspending() }
+ }
+
+ @Test
+ fun verifySuspendFunctionCalled_runBlocking() = runBlocking<Unit> {
+ val m = mock<SomeInterface>()
+
+ m.suspending()
+
+ verify(m).suspending()
+ }
+
+ @Test
+ fun verifySuspendFunctionCalled_verifyBlocking() {
+ val m = mock<SomeInterface>()
+
+ runBlocking { m.suspending() }
+
+ verifyBlocking(m) { suspending() }
+ }
+
+ @Test
+ fun verifyAtLeastOnceSuspendFunctionCalled_verifyBlocking() {
+ val m = mock<SomeInterface>()
+
+ runBlocking { m.suspending() }
+ runBlocking { m.suspending() }
+
+ verifyBlocking(m, atLeastOnce()) { suspending() }
+ }
+
+ @Test
+ fun verifySuspendMethod() = runBlocking {
+ val testSubject: SomeInterface = mock()
+
+ testSubject.suspending()
+
+ inOrder(testSubject) {
+ verify(testSubject).suspending()
+ }
+ }
+}
+
+interface SomeInterface {
+
+ suspend fun suspending(): Int
+ fun nonsuspending(): Int
+}
+
+class SomeClass {
+
+ suspend fun result(r: Int) = withContext(Dispatchers.Default) { r }
+
+ suspend fun delaying() = withContext(Dispatchers.Default) {
+ delay(100)
+ 42
+ }
+}
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
new file mode 100644
index 0000000..5086f47
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include 'mockito-kotlin'
+include 'tests' \ No newline at end of file
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..24ab716
--- /dev/null
+++ b/tests/build.gradle
@@ -0,0 +1,29 @@
+buildscript {
+ ext.kotlin_version = System.getenv("KOTLIN_VERSION") ?: '1.3.50'
+ println "$project uses Kotlin $kotlin_version"
+
+ 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-${version}.jar")
+
+ compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ compile "org.mockito:mockito-core:2.23.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..703e750
--- /dev/null
+++ b/tests/src/test/kotlin/test/ArgumentCaptorTest.kt
@@ -0,0 +1,229 @@
+package test
+
+import com.nhaarman.expect.expect
+import com.nhaarman.expect.expectErrorWithMessage
+import org.junit.Test
+import org.mockito.kotlin.*
+import java.util.*
+
+class ArgumentCaptorTest : TestBase() {
+
+ @Test
+ fun argumentCaptor_withSingleValue() {
+ /* Given */
+ val date: Date = mock()
+
+ /* When */
+ date.time = 5L
+
+ /* Then */
+ val captor = argumentCaptor<Long>()
+ verify(date).time = captor.capture()
+ expect(captor.lastValue).toBe(5L)
+ }
+
+ @Test
+ fun argumentCaptor_destructuring2() {
+ /* Given */
+ val date: Date = mock()
+
+ /* When */
+ date.time = 5L
+
+ /* Then */
+ val (captor1, captor2) = argumentCaptor<Long, Long>()
+ 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) = argumentCaptor<Long, Long, Long>()
+ val verifyCaptor: KArgumentCaptor<Long>.() -> 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) = argumentCaptor<Long, Long, Long, Long>()
+ val verifyCaptor: KArgumentCaptor<Long>.() -> 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) = argumentCaptor<Long, Long, Long, Long, Long>()
+ val verifyCaptor: KArgumentCaptor<Long>.() -> 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 */
+ val m: Methods = mock()
+
+ /* When */
+ m.nullableString(null)
+
+ /* Then */
+ val captor = argumentCaptor<String>()
+ 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<String>()
+ 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<Long>()
+ verify(date, times(2)).time = captor.capture()
+ expect(captor.allValues).toBe(listOf(5, 7))
+ }
+
+ @Test
+ fun argumentCaptor_multipleValuesIncludingNull() {
+ /* Given */
+ val m: Methods = mock()
+
+ /* When */
+ m.nullableString("test")
+ m.nullableString(null)
+
+ /* Then */
+ val captor = nullableArgumentCaptor<String>()
+ verify(m, times(2)).nullableString(captor.capture())
+ expect(captor.allValues).toBe(listOf("test", null))
+ }
+
+ @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<Int>().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<Int>().apply {
+ verify(m).int(capture())
+
+ expect(secondValue).toBe(2)
+ }
+ }
+
+ @Test
+ fun argumentCaptor_withSingleValue_lambda() {
+ /* Given */
+ val date: Date = mock()
+
+ /* When */
+ date.time = 5L
+
+ /* Then */
+ argumentCaptor<Long> {
+ 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<Long> {
+ verify(date).time = capture()
+ expect(lastValue).toBe(3L)
+ }
+ }
+ }
+}
diff --git a/tests/src/test/kotlin/test/BDDMockitoTest.kt b/tests/src/test/kotlin/test/BDDMockitoTest.kt
new file mode 100644
index 0000000..0472163
--- /dev/null
+++ b/tests/src/test/kotlin/test/BDDMockitoTest.kt
@@ -0,0 +1,131 @@
+package test
+
+import com.nhaarman.expect.expect
+import org.junit.Test
+import org.mockito.kotlin.*
+import org.mockito.stubbing.Answer
+
+class BDDMockitoTest {
+
+ @Test
+ fun given_will_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ given(mock.stringResult()) will Answer<String> { "Test" }
+
+ /* Then */
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun given_willReturn_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ given(mock.stringResult()).willReturn("Test")
+
+ /* Then */
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun givenLambda_willReturn_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ given { mock.stringResult() }.willReturn("Test")
+
+ /* Then */
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun given_willReturnLambda_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ given(mock.stringResult()).willReturn { "Test" }
+
+ /* Then */
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun givenLambda_willReturnLambda_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ given { mock.stringResult() } willReturn { "Test" }
+
+ /* Then */
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun given_willAnswer_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ given(mock.stringResult()).willAnswer { "Test" }
+
+ /* Then */
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun given_willAnswerInfix_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ given(mock.stringResult()) willAnswer { "Test" }
+
+ /* Then */
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun given_willAnswerInfix_withInvocationInfo_properlyStubs() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* 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 */
+ val mock = mock<Methods>()
+
+ /* When */
+ given(mock.stringResult()) willThrow { IllegalStateException() }
+ mock.stringResult()
+ }
+
+ @Test
+ fun then() {
+ /* Given */
+ val mock = mock<Methods>()
+ whenever(mock.stringResult()).thenReturn("Test")
+
+ /* When */
+ mock.stringResult()
+
+ /* Then */
+ org.mockito.kotlin.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..87b758d
--- /dev/null
+++ b/tests/src/test/kotlin/test/Classes.kt
@@ -0,0 +1,108 @@
+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<Closed>)
+ fun closedNullableArray(a: Array<Closed?>)
+ fun closedCollection(c: Collection<Closed>)
+ fun closedList(c: List<Closed>)
+ fun closedStringMap(m: Map<Closed, String>)
+ fun closedSet(s: Set<Closed>)
+ 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?)
+
+ fun stringResult(): String
+ fun stringResult(s: String): String
+ fun nullableStringResult(): String?
+ fun builderMethod(): Methods
+ fun varargBooleanResult(vararg values: String): Boolean
+
+ fun nonDefaultReturnType(): ExtraInterface
+}
+
+interface ExtraInterface
+
+abstract class ThrowingConstructor {
+
+ constructor() {
+ error("Error in constructor")
+ }
+}
+
+abstract class ThrowingConstructorWithArgument {
+
+ constructor(s: String) {
+ error("Error in constructor: $s")
+ }
+}
+
+abstract class NonThrowingConstructorWithArgument {
+
+ constructor() {
+ error("Error in constructor")
+ }
+
+ @Suppress("UNUSED_PARAMETER")
+ constructor(s: String)
+}
+
+interface GenericMethods<T> {
+ 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..2f64c09
--- /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 org.mockito.kotlin.eq
+import org.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
+ 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..afed69f
--- /dev/null
+++ b/tests/src/test/kotlin/test/MatchersTest.kt
@@ -0,0 +1,334 @@
+package test
+
+import com.nhaarman.expect.expect
+import com.nhaarman.expect.expectErrorWithMessage
+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() {
+
+ @Test
+ fun anyString() {
+ mock<Methods>().apply {
+ string("")
+ verify(this).string(any())
+ }
+ }
+
+ @Test
+ fun anyInt() {
+ mock<Methods>().apply {
+ int(3)
+ verify(this).int(any())
+ }
+ }
+
+ @Test
+ fun anyClosedClass() {
+ mock<Methods>().apply {
+ closed(Closed())
+ verify(this).closed(any())
+ }
+ }
+
+ @Test
+ fun anyIntArray() {
+ mock<Methods>().apply {
+ intArray(intArrayOf())
+ verify(this).intArray(any())
+ }
+ }
+
+ @Test
+ fun anyClassArray() {
+ mock<Methods>().apply {
+ closedArray(arrayOf(Closed()))
+ verify(this).closedArray(anyArray())
+ }
+ }
+
+ @Test
+ fun anyNullableClassArray() {
+ mock<Methods>().apply {
+ closedNullableArray(arrayOf(Closed(), null))
+ verify(this).closedNullableArray(anyArray())
+ }
+ }
+
+ @Test
+ fun anyStringVararg() {
+ mock<Methods>().apply {
+ closedVararg(Closed(), Closed())
+ verify(this).closedVararg(anyVararg())
+ }
+ }
+
+ @Test
+ fun anyNull_neverVerifiesAny() {
+ mock<Methods>().apply {
+ nullableString(null)
+ verify(this, never()).nullableString(any())
+ }
+ }
+
+ @Test
+ fun anyNull_verifiesAnyOrNull() {
+ mock<Methods>().apply {
+ nullableString(null)
+ verify(this).nullableString(anyOrNull())
+ }
+ }
+
+ @Test
+ fun anyNull_forPrimitiveBoolean() {
+ mock<Methods>().apply {
+ boolean(false)
+ verify(this).boolean(anyOrNull())
+ }
+ }
+ @Test
+ fun anyNull_forPrimitiveByte() {
+ mock<Methods>().apply {
+ byte(3)
+ verify(this).byte(anyOrNull())
+ }
+ }
+
+ @Test
+ fun anyNull_forPrimitiveChar() {
+ mock<Methods>().apply {
+ char('a')
+ verify(this).char(anyOrNull())
+ }
+ }
+
+ @Test
+ fun anyNull_forPrimitiveShort() {
+ mock<Methods>().apply {
+ short(3)
+ verify(this).short(anyOrNull())
+ }
+ }
+
+ @Test
+ fun anyNull_forPrimitiveInt() {
+ mock<Methods>().apply {
+ int(3)
+ verify(this).int(anyOrNull())
+ }
+ }
+
+ @Test
+ fun anyNull_forPrimitiveLong() {
+ mock<Methods>().apply {
+ long(3)
+ verify(this).long(anyOrNull())
+ }
+ }
+
+ @Test
+ fun anyNull_forPrimitiveFloat() {
+ mock<Methods>().apply {
+ float(3f)
+ verify(this).float(anyOrNull())
+ }
+ }
+
+ @Test
+ fun anyNull_forPrimitiveDouble() {
+ mock<Methods>().apply {
+ double(3.0)
+ verify(this).double(anyOrNull())
+ }
+ }
+
+ /** https://github.com/nhaarman/mockito-kotlin/issues/27 */
+ @Test
+ fun anyThrowableWithSingleThrowableConstructor() {
+ mock<Methods>().apply {
+ throwableClass(ThrowableClass(IOException()))
+ verify(this).throwableClass(any())
+ }
+ }
+
+ @Test
+ fun listArgThat() {
+ mock<Methods>().apply {
+ closedList(listOf(Closed(), Closed()))
+ verify(this).closedList(
+ argThat {
+ size == 2
+ }
+ )
+ }
+ }
+
+ @Test
+ fun listArgForWhich() {
+ mock<Methods>().apply {
+ closedList(listOf(Closed(), Closed()))
+ verify(this).closedList(
+ argForWhich {
+ size == 2
+ }
+ )
+ }
+ }
+
+ @Test
+ fun listArgWhere() {
+ mock<Methods>().apply {
+ closedList(listOf(Closed(), Closed()))
+ verify(this).closedList(
+ argWhere {
+ it.size == 2
+ }
+ )
+ }
+ }
+
+ @Test
+ fun listArgCheck() {
+ mock<Methods>().apply {
+ closedList(listOf(Closed(), Closed()))
+ verify(this).closedList(
+ check {
+ expect(it.size).toBe(2)
+ }
+ )
+ }
+ }
+
+ @Test
+ fun checkProperlyFails() {
+ mock<Methods>().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<Methods>().apply {
+ nullableString(null)
+
+ expectErrorWithMessage("null").on {
+ verify(this).nullableString(check {})
+ }
+ }
+ }
+
+
+ @Test
+ fun isA_withNonNullableString() {
+ mock<Methods>().apply {
+ string("")
+ verify(this).string(isA<String>())
+ }
+ }
+
+ @Test
+ fun isA_withNullableString() {
+ mock<Methods>().apply {
+ nullableString("")
+ verify(this).nullableString(isA<String>())
+ }
+ }
+
+ @Test
+ fun same_withNonNullArgument() {
+ mock<Methods>().apply {
+ string("")
+ verify(this).string(same(""))
+ }
+ }
+
+ @Test
+ fun same_withNullableNonNullArgument() {
+ mock<Methods>().apply {
+ nullableString("")
+ verify(this).nullableString(same(""))
+ }
+ }
+
+ @Test
+ fun same_withNullArgument() {
+ mock<Methods>().apply {
+ nullableString(null)
+ verify(this).nullableString(same(null))
+ }
+ }
+
+ @Test
+ fun testVarargAnySuccess() {
+ /* Given */
+ val t = mock<Methods>()
+ // a matcher to check if any of the varargs was equals to "b"
+ val matcher = VarargAnyMatcher<String, Boolean>({ "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<Methods>()
+ // a matcher to check if any of the varargs was equals to "d"
+ val matcher = VarargAnyMatcher<String, Boolean>({ "d" == it }, true, false)
+
+ /* When */
+ whenever(t.varargBooleanResult(argThat(matcher))).thenAnswer(matcher)
+
+ /* Then */
+ expect(t.varargBooleanResult("a", "b", "c")).toBe(false)
+ }
+
+ /** https://github.com/nhaarman/mockito-kotlin/issues/328 */
+ @Test
+ fun testRefEqForNonNullableParameter() {
+ mock<Methods>().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.
+ */
+ private class VarargAnyMatcher<T, R>(
+ private val match: ((T) -> Boolean),
+ private val success: R,
+ private val failure: R
+ ) : ArgumentMatcher<T>, VarargMatcher, Answer<R> {
+ 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/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..43e6413
--- /dev/null
+++ b/tests/src/test/kotlin/test/MockingTest.kt
@@ -0,0 +1,357 @@
+package test
+
+import com.nhaarman.expect.expect
+import com.nhaarman.expect.expectErrorWithMessage
+import com.nhaarman.expect.fail
+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
+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<MyClass>()
+
+ 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<Open>() {
+ on { stringResult() } doReturn "A"
+ }
+
+ /* When */
+ val result = mock.stringResult()
+
+ /* Then */
+ expect(result).toBe("A")
+ }
+
+ @Test
+ fun testMockStubbing_normalOverridesLambda() {
+ /* Given */
+ val mock = mock<Open>() {
+ 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<Methods>(defaultAnswer = Mockito.RETURNS_SELF)
+
+ /* When */
+ val result = mock.builderMethod()
+
+ /* Then */
+ expect(result).toBe(mock)
+ }
+
+ @Test
+ fun mock_withSettingsAPI_extraInterfaces() {
+ /* Given */
+ val mock = mock<Methods>(
+ extraInterfaces = arrayOf(ExtraInterface::class)
+ )
+
+ /* Then */
+ expect(mock).toBeInstanceOf<ExtraInterface>()
+ }
+
+ @Test
+ fun mock_withSettingsAPI_name() {
+ /* Given */
+ val mock = mock<Methods>(name = "myName")
+
+ /* When */
+ expectErrorWithMessage("myName.stringResult()") on {
+ verify(mock).stringResult()
+ }
+ }
+
+ @Test
+ fun mock_withSettingsAPI_defaultAnswer() {
+ /* Given */
+ val mock = mock<Methods>(defaultAnswer = Mockito.RETURNS_MOCKS)
+
+ /* When */
+ val result = mock.nonDefaultReturnType()
+
+ /* Then */
+ expect(result).toNotBeNull()
+ }
+
+ @Test
+ fun mock_withSettingsAPI_serializable() {
+ /* Given */
+ val mock = mock<Methods>(serializable = true)
+
+ /* Then */
+ expect(mock).toBeInstanceOf<Serializable>()
+ }
+
+ @Test
+ fun mock_withSettingsAPI_serializableMode() {
+ /* Given */
+ val mock = mock<Methods>(serializableMode = BASIC)
+
+ /* Then */
+ expect(mock).toBeInstanceOf<Serializable>()
+ }
+
+ @Test
+ fun mock_withSettingsAPI_verboseLogging() {
+ /* Given */
+ val out = mock<PrintStream>()
+ System.setOut(out)
+ val mock = mock<Methods>(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<Methods>(invocationListeners = arrayOf(InvocationListener { bool = true }))
+
+ /* When */
+ mock.stringResult()
+
+ /* Then */
+ expect(bool).toHold()
+ }
+
+ @Test
+ fun mock_withSettingsAPI_stubOnly() {
+ /* Given */
+ val mock = mock<Methods>(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<ThrowingConstructor>(useConstructor = parameterless()) {}
+ }
+ }
+
+ @Test
+ fun mock_withSettingsAPI_useConstructorWithArguments_failing() {
+ /* Given */
+ expectErrorWithMessage("Unable to create mock instance of type ") on {
+ mock<ThrowingConstructorWithArgument>(useConstructor = withArguments("Test")) {}
+ }
+ }
+
+ @Test
+ fun mock_withSettingsAPI_useConstructorWithArguments() {
+ /* When */
+ val result = mock<NonThrowingConstructorWithArgument>(useConstructor = withArguments("Test")) {}
+
+ /* Then */
+ expect(result).toNotBeNull()
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPI_extraInterfaces() {
+ /* Given */
+ val mock = mock<Methods>(extraInterfaces = arrayOf(ExtraInterface::class)) {}
+
+ /* Then */
+ expect(mock).toBeInstanceOf<ExtraInterface>()
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPI_name() {
+ /* Given */
+ val mock = mock<Methods>(name = "myName") {}
+
+ /* When */
+ expectErrorWithMessage("myName.stringResult()") on {
+ verify(mock).stringResult()
+ }
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPIAndStubbing_name() {
+ /* Given */
+ val mock = mock<Methods>(name = "myName") {
+ on { nullableStringResult() } doReturn "foo"
+ }
+
+ /* When */
+ val result = mock.nullableStringResult()
+
+ /* Then */
+ expect(result).toBe("foo")
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPI_defaultAnswer() {
+ /* Given */
+ val mock = mock<Methods>(defaultAnswer = Mockito.RETURNS_MOCKS) {}
+
+ /* When */
+ val result = mock.nonDefaultReturnType()
+
+ /* Then */
+ expect(result).toNotBeNull()
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPI_serializable() {
+ /* Given */
+ val mock = mock<Methods>(serializable = true) {}
+
+ /* Then */
+ expect(mock).toBeInstanceOf<Serializable>()
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPI_serializableMode() {
+ /* Given */
+ val mock = mock<Methods>(serializableMode = BASIC) {}
+
+ /* Then */
+ expect(mock).toBeInstanceOf<Serializable>()
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPI_verboseLogging() {
+ /* Given */
+ val out = mock<PrintStream>()
+ System.setOut(out)
+ val mock = mock<Methods>(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<Methods>(invocationListeners = arrayOf(InvocationListener { bool = true })) {}
+
+ /* When */
+ mock.stringResult()
+
+ /* Then */
+ expect(bool).toHold()
+ }
+
+ @Test
+ fun mockStubbing_withSettingsAPI_stubOnly() {
+ /* Given */
+ val mock = mock<Methods>(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<ThrowingConstructor>(useConstructor = parameterless()) {}
+ }
+ }
+
+ 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..3c9268e
--- /dev/null
+++ b/tests/src/test/kotlin/test/OngoingStubbingTest.kt
@@ -0,0 +1,340 @@
+package test
+
+import com.nhaarman.expect.expect
+import com.nhaarman.expect.expectErrorWithMessage
+import com.nhaarman.expect.fail
+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() {
+
+ @Test
+ fun testOngoingStubbing_methodCall() {
+ /* Given */
+ val mock = mock<Open>()
+ mock<Open> {
+ on(mock.stringResult()).doReturn("A")
+ }
+
+ /* When */
+ val result = mock.stringResult()
+
+ /* Then */
+ expect(result).toBe("A")
+ }
+
+ @Test
+ fun testOngoingStubbing_builder() {
+ /* Given */
+ val mock = mock<Methods> { mock ->
+ on { builderMethod() } doReturn mock
+ }
+
+ /* When */
+ val result = mock.builderMethod()
+
+ /* Then */
+ expect(result).toBeTheSameAs(mock)
+ }
+
+ @Test
+ fun testOngoingStubbing_nullable() {
+ /* Given */
+ val mock = mock<Methods> {
+ on { nullableStringResult() } doReturn "Test"
+ }
+
+ /* When */
+ val result = mock.nullableStringResult()
+
+ /* Then */
+ expect(result).toBe("Test")
+ }
+
+ @Test
+ fun testOngoingStubbing_doThrow() {
+ /* Given */
+ val mock = mock<Methods> {
+ on { builderMethod() } doThrow IllegalArgumentException()
+ }
+
+ try {
+ /* When */
+ mock.builderMethod()
+ fail("No exception thrown")
+ } catch (e: IllegalArgumentException) {
+ }
+ }
+
+ @Test
+ fun testOngoingStubbing_doThrowClass() {
+ /* Given */
+ val mock = mock<Methods> {
+ on { builderMethod() } doThrow IllegalArgumentException::class
+ }
+
+ try {
+ /* When */
+ mock.builderMethod()
+ fail("No exception thrown")
+ } catch (e: IllegalArgumentException) {
+ }
+ }
+
+ @Test
+ fun testOngoingStubbing_doThrowVarargs() {
+ /* Given */
+ val mock = mock<Methods> {
+ 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<Methods> {
+ 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<Methods> {
+ on { stringResult() } doAnswer { "result" }
+ }
+
+ /* When */
+ val result = mock.stringResult()
+
+ /* Then */
+ expect(result).toBe("result")
+ }
+
+ @Test
+ fun testOngoingStubbing_doAnswer_instance() {
+ /* Given */
+ val mock = mock<Methods> {
+ on { stringResult() } doAnswer Answer<String> { "result" }
+ }
+
+ /* When */
+ val result = mock.stringResult()
+
+ /* Then */
+ expect(result).toBe("result")
+ }
+
+ @Test
+ fun testOngoingStubbing_doAnswer_returnsSelf() {
+ /* Given */
+ val mock = mock<Methods> {
+ 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<Methods> {
+ 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<Methods>()
+
+ //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<Methods> {
+ 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<Methods> {
+ 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<Methods> {
+ on { stringResult(check { }) } doReturn "A"
+ on { stringResult(check { }) } doReturn "B"
+ }
+ }
+ }
+
+ @Test
+ fun doReturn_withSingleItemList() {
+ /* Given */
+ val mock = mock<Open> {
+ on { stringResult() } doReturnConsecutively 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<Open> {
+ on { throwsNPE() } doReturn "result"
+ }
+ }
+ }
+
+ @Test
+ fun doReturn_withGenericIntReturnType_on() {
+ /* Expect */
+ expectErrorWithMessage("onGeneric") on {
+
+ /* When */
+ mock<GenericMethods<Int>> {
+ on { genericMethod() } doReturn 2
+ }
+ }
+ }
+
+ @Test
+ fun doReturn_withGenericIntReturnType_onGeneric() {
+ /* Given */
+ val mock = mock<GenericMethods<Int>> {
+ onGeneric { genericMethod() } doReturn 2
+ }
+
+ /* Then */
+ expect(mock.genericMethod()).toBe(2)
+ }
+
+ @Test
+ fun doReturn_withGenericNullableReturnType_onGeneric() {
+ val m = mock<GenericMethods<String>> {
+ onGeneric { nullableReturnType() } doReturn "Test"
+ }
+
+ expect(m.nullableReturnType()).toBe("Test")
+ }
+
+ @Test
+ fun stubbingExistingMock() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ stubbing(mock) {
+ on { stringResult() } doReturn "result"
+ }
+
+ /* Then */
+ expect(mock.stringResult()).toBe("result")
+ }
+
+ @Test
+ fun testMockitoStackOnUnfinishedStubbing() {
+ /* Given */
+ val mock = mock<Open>()
+ 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")
+ }
+ }
+}
diff --git a/tests/src/test/kotlin/test/SpyTest.kt b/tests/src/test/kotlin/test/SpyTest.kt
new file mode 100644
index 0000000..500faee
--- /dev/null
+++ b/tests/src/test/kotlin/test/SpyTest.kt
@@ -0,0 +1,141 @@
+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 org.junit.After
+import org.junit.Test
+import org.mockito.Mockito
+import org.mockito.kotlin.*
+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<Date> {
+ 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)
+ }
+
+ @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
+}
+
diff --git a/tests/src/test/kotlin/test/StubberTest.kt b/tests/src/test/kotlin/test/StubberTest.kt
new file mode 100644
index 0000000..eb6e28c
--- /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 org.junit.Test
+import org.mockito.kotlin.*
+
+class StubberTest : TestBase() {
+
+ @Test
+ fun testDoAnswer() {
+ val mock = mock<Methods>()
+
+ doAnswer { "Test" }
+ .whenever(mock)
+ .stringResult()
+
+ expect(mock.stringResult()).toBe("Test")
+ }
+
+ @Test
+ fun testDoCallRealMethod() {
+ val mock = mock<Open>()
+
+ 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<Methods>()
+
+ doReturn("test").whenever(mock).stringResult()
+
+ expect(mock.stringResult()).toBe("test")
+ }
+
+ @Test
+ fun testDoReturnNullValue() {
+ val mock = mock<Methods>()
+
+ doReturn(null).whenever(mock).stringResult()
+
+ expect(mock.stringResult()).toBeNull()
+ }
+
+ @Test
+ fun testDoReturnNullValues() {
+ val mock = mock<Methods>()
+
+ doReturn(null, null).whenever(mock).stringResult()
+
+ expect(mock.stringResult()).toBeNull()
+ expect(mock.stringResult()).toBeNull()
+ }
+
+ @Test
+ fun testDoReturnValues() {
+ val mock = mock<Methods>()
+
+ doReturn("test", "test2").whenever(mock).stringResult()
+
+ expect(mock.stringResult()).toBe("test")
+ expect(mock.stringResult()).toBe("test2")
+ }
+
+ @Test
+ fun testDoThrowClass() {
+ val mock = mock<Open>()
+
+ doThrow(IllegalStateException::class).whenever(mock).go()
+
+ try {
+ mock.go()
+ throw AssertionError("Call should have thrown.")
+ } catch (e: IllegalStateException) {
+ }
+ }
+
+ @Test
+ fun testDoThrow() {
+ val mock = mock<Open>()
+
+ 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..f2f92fd
--- /dev/null
+++ b/tests/src/test/kotlin/test/VerificationTest.kt
@@ -0,0 +1,115 @@
+package test
+
+import com.nhaarman.expect.expect
+import org.junit.Test
+import org.mockito.exceptions.base.MockitoAssertionError
+import org.mockito.kotlin.*
+import org.mockito.kotlin.verify
+
+class VerificationTest : TestBase() {
+
+ @Test
+ fun atLeastXInvocations() {
+ mock<Methods>().apply {
+ string("")
+ string("")
+
+ verify(this, atLeast(2)).string(any())
+ }
+ }
+
+ @Test
+ fun testAtLeastOnce() {
+ mock<Methods>().apply {
+ string("")
+ string("")
+
+ verify(this, atLeastOnce()).string(any())
+ }
+ }
+
+ @Test
+ fun atMostXInvocations() {
+ mock<Methods>().apply {
+ string("")
+ string("")
+
+ verify(this, atMost(2)).string(any())
+ }
+ }
+
+ @Test
+ fun testCalls() {
+ mock<Methods>().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 testInOrderWithReceiver() {
+ /* Given */
+ val mock = mock<Methods>()
+
+ /* When */
+ mock.string("")
+ mock.int(0)
+
+ /* Then */
+ mock.inOrder {
+ verify().string(any())
+ verify().int(any())
+ verifyNoMoreInteractions()
+ }
+ }
+
+ @Test
+ fun testClearInvocations() {
+ val mock = mock<Methods>().apply {
+ string("")
+ }
+
+ clearInvocations(mock)
+
+ verify(mock, never()).string(any())
+ }
+
+ @Test
+ fun testDescription() {
+ try {
+ mock<Methods>().apply {
+ verify(this, description("Test")).string(any())
+ }
+ throw AssertionError("Verify should throw Exception.")
+ } catch (e: MockitoAssertionError) {
+ expect(e.message).toContain("Test")
+ }
+ }
+
+ @Test
+ fun testAfter() {
+ mock<Methods>().apply {
+ int(3)
+ verify(this, after(10)).int(3)
+ }
+ }
+} \ 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..0a93832
--- /dev/null
+++ b/tests/src/test/kotlin/test/VerifyTest.kt
@@ -0,0 +1,96 @@
+package test
+
+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
+
+class VerifyTest : TestBase() {
+
+ @Test
+ fun verify0Calls() {
+ val iface = mock<TestInterface>()
+
+ verify(iface) {
+ 0 * { call(any()) }
+ }
+ }
+
+ @Test
+ fun verifyNCalls() {
+ val iface = mock<TestInterface>()
+
+ iface.call(42)
+ iface.call(42)
+
+ verify(iface) {
+ 2 * { call(42) }
+ }
+ }
+
+ @Test(expected = TooLittleActualInvocations::class)
+ fun verifyFailsWithWrongCount() {
+ val iface = mock<TestInterface>()
+
+ iface.call(0)
+
+ verify(iface) {
+ 2 * { call(0) }
+ }
+ }
+
+ @Test(expected = ArgumentsAreDifferent::class)
+ fun verifyFailsWithWrongArg() {
+ val iface = mock<TestInterface>()
+
+ iface.call(3)
+
+ verify(iface) {
+ 1 * { call(0) }
+ }
+ }
+
+ @Test
+ fun verifyDefaultArgs_firstParameter() {
+ /* Given */
+ val m = mock<TestInterface>()
+
+ /* When */
+ m.defaultArgs(a = 2)
+
+ /* Then */
+ verify(m).defaultArgs(2)
+ }
+
+ @Test
+ fun verifyDefaultArgs_secondParameter() {
+ /* Given */
+ val m = mock<TestInterface>()
+
+ /* When */
+ m.defaultArgs(b = 2)
+
+ /* Then */
+ verify(m).defaultArgs(b = 2)
+ }
+
+ @Test
+ fun verifyDefaultArgs_verifyDefaultValue() {
+ /* Given */
+ val m = mock<TestInterface>()
+
+ /* 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
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..6d160c7
--- /dev/null
+++ b/tests/src/test/kotlin/test/createinstance/NullCasterTest.kt
@@ -0,0 +1,31 @@
+package test.createinstance
+
+import com.nhaarman.expect.expect
+import org.mockito.kotlin.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..b03d77e
--- /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 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
+
+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<ClassToBeMocked>()
+
+ /* Then */
+ expect(result).toNotBeNull()
+ }
+
+ @Test
+ fun anyClosedClass() {
+ /* Given */
+ val mock = mock<ClassToBeMocked>()
+
+ /* When */
+ mock.doSomething(mock)
+
+ /* Then */
+ verify(mock).doSomething(any())
+ }
+
+ @Test
+ fun mockClosedFunction_mockStubbing() {
+ /* Given */
+ val mock = mock<ClassToBeMocked> {
+ 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<ClassToBeMocked>()
+ 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<Methods>().apply {
+ throwableClass(ThrowableClass(IOException()))
+ verify(this).throwableClass(any())
+ }
+ }
+
+ interface Methods {
+
+ fun throwableClass(t: ThrowableClass)
+ }
+
+ class ThrowableClass(cause: Throwable) : Throwable(cause)
+
+}
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 <version>" >&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"
diff --git a/version.properties b/version.properties
new file mode 100644
index 0000000..708e7ad
--- /dev/null
+++ b/version.properties
@@ -0,0 +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.2.*
+tagPrefix= \ No newline at end of file