├── .github
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── ci.yml
├── .gitignore
├── .idea
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── copyright
│ ├── MIT.xml
│ └── profiles_settings.xml
└── inspectionProfiles
│ └── Project_Default.xml
├── LICENSE
├── README.md
├── RELEASING.md
├── build.gradle
├── gradle.properties
├── gradle
├── publishing.gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── mockito-kotlin
├── build.gradle
└── src
│ ├── main
│ └── kotlin
│ │ └── org
│ │ └── mockito
│ │ └── kotlin
│ │ ├── AdditionalMatchers.kt
│ │ ├── ArgumentCaptor.kt
│ │ ├── BDDMockito.kt
│ │ ├── KInOrder.kt
│ │ ├── KInvocationOnMock.kt
│ │ ├── KStubbing.kt
│ │ ├── LenientStubber.kt
│ │ ├── Matchers.kt
│ │ ├── Mocking.kt
│ │ ├── Mockito.kt
│ │ ├── MockitoKotlinException.kt
│ │ ├── OngoingStubbing.kt
│ │ ├── Spying.kt
│ │ ├── Stubber.kt
│ │ ├── Verification.kt
│ │ ├── VerifyScope.kt
│ │ └── internal
│ │ ├── CreateInstance.kt
│ │ ├── KAnswer.kt
│ │ ├── KInOrderDecorator.kt
│ │ └── SuspendableAnswer.kt
│ └── test
│ └── kotlin
│ ├── org
│ └── mockito
│ │ └── kotlin
│ │ └── BDDMockitoKtTest.kt
│ └── test
│ └── CoroutinesTest.kt
├── ops
├── mockMakerInline.sh
└── org.mockito.plugins.MockMaker
├── settings.gradle
├── tests
├── README.md
├── build.gradle
├── gradle.properties
├── settings.gradle
└── src
│ └── test
│ └── kotlin
│ └── test
│ ├── AdditionalMatchersTest.kt
│ ├── ArgumentCaptorTest.kt
│ ├── BDDMockitoTest.kt
│ ├── Classes.kt
│ ├── EqTest.kt
│ ├── LenientStubberTest.kt
│ ├── MatchersTest.kt
│ ├── MockMaker.kt
│ ├── MockingTest.kt
│ ├── OngoingStubbingTest.kt
│ ├── SpyTest.kt
│ ├── StubberTest.kt
│ ├── TestBase.kt
│ ├── VerificationTest.kt
│ ├── VerifyTest.kt
│ ├── createinstance
│ └── NullCasterTest.kt
│ └── inline
│ └── UsingMockMakerInlineTest.kt
└── version.properties
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Thank you for submitting a pull request! But first:
2 |
3 | - [ ] Can you back your code up with tests?
4 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | #
2 | # CI build that assembles artifacts and runs tests.
3 | # If validation is successful this workflow releases from the main dev branch.
4 | #
5 | # - skipping CI: add [skip ci] to the commit message
6 | # - skipping release: add [skip release] to the commit message
7 | #
8 | name: CI
9 |
10 | on:
11 | push:
12 | branches:
13 | - main
14 | tags:
15 | - 5.*
16 | pull_request:
17 | branches:
18 | - main
19 |
20 | jobs:
21 |
22 | #
23 | # SINGLE-JOB
24 | #
25 | verify:
26 | runs-on: ubuntu-latest
27 | if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')"
28 |
29 | steps:
30 |
31 | - name: 1. Check out code
32 | uses: actions/checkout@v2 # https://github.com/actions/checkout
33 |
34 | - name: 2. Set up Java 11
35 | uses: actions/setup-java@v1 # https://github.com/actions/setup-java
36 | with:
37 | java-version: 11
38 |
39 | - name: 3. Validate Gradle wrapper
40 | uses: gradle/wrapper-validation-action@v1 # https://github.com/gradle/wrapper-validation-action
41 |
42 | #
43 | # Main build job
44 | #
45 | build:
46 | needs: [verify]
47 | runs-on: ubuntu-latest
48 |
49 | # Definition of the build matrix
50 | strategy:
51 | matrix:
52 | mock-maker: ['mock-maker-default', 'mock-maker-inline']
53 | kotlin: ['1.9.20']
54 | # Note that the old Travis CI referenced other Kotlin versions: '1.0.7', '1.1.61', '1.2.50'
55 | # However, those versions of Kotlin don't work with latest Gradle
56 |
57 | steps:
58 |
59 | - name: 1. Check out code
60 | uses: actions/checkout@v2 # https://github.com/actions/checkout
61 |
62 | - name: 2. Set up Java 11
63 | uses: actions/setup-java@v1 # https://github.com/actions/setup-java
64 | with:
65 | java-version: 11
66 |
67 | - name: 3. Build with Kotlin ${{ matrix.kotlin }} and mock-maker ${{ matrix.mock-maker }}
68 | run: |
69 | ops/mockMakerInline.sh
70 | ./gradlew build -PtestKotlinVersion=${{ matrix.kotlin }}
71 | env:
72 | MOCK_MAKER: ${{ matrix.mock-maker }}
73 |
74 | #
75 | # Release job, only for pushes to the main development branch
76 | #
77 | release:
78 | runs-on: ubuntu-latest
79 | needs: [build] # build job must pass before we can release
80 |
81 | if: github.event_name == 'push'
82 | && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/5.'))
83 | && github.repository == 'mockito/mockito-kotlin'
84 | && !contains(toJSON(github.event.commits.*.message), '[skip release]')
85 |
86 | steps:
87 |
88 | - name: Check out code
89 | uses: actions/checkout@v2 # https://github.com/actions/checkout
90 | with:
91 | fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci
92 |
93 | - name: Set up Java 11
94 | uses: actions/setup-java@v1
95 | with:
96 | java-version: 11
97 |
98 | - name: Build and release
99 | run: ./gradlew githubRelease publishToSonatype closeAndReleaseStagingRepository releaseSummary
100 | env:
101 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
102 | NEXUS_TOKEN_USER: ${{secrets.NEXUS_TOKEN_USER}}
103 | NEXUS_TOKEN_PWD: ${{secrets.NEXUS_TOKEN_PWD}}
104 | PGP_KEY: ${{secrets.PGP_KEY}}
105 | PGP_PWD: ${{secrets.PGP_PWD}}
106 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 | out/
4 | repo
5 |
6 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
7 | !gradle-wrapper.jar
8 |
9 | # intelliJ
10 | .idea/
11 | *.iml
12 |
13 | *.orig
14 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
40 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | xmlns:android
117 | ^$
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | xmlns:.*
127 | ^$
128 |
129 |
130 | BY_NAME
131 |
132 |
133 |
134 |
135 |
136 |
137 | .*:id
138 | http://schemas.android.com/apk/res/android
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | .*:name
148 | http://schemas.android.com/apk/res/android
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | name
158 | ^$
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 | style
168 | ^$
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 | .*
178 | ^$
179 |
180 |
181 | BY_NAME
182 |
183 |
184 |
185 |
186 |
187 |
188 | .*:layout_width
189 | http://schemas.android.com/apk/res/android
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | .*:layout_height
199 | http://schemas.android.com/apk/res/android
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | .*:layout_.*
209 | http://schemas.android.com/apk/res/android
210 |
211 |
212 | BY_NAME
213 |
214 |
215 |
216 |
217 |
218 |
219 | .*:width
220 | http://schemas.android.com/apk/res/android
221 |
222 |
223 | BY_NAME
224 |
225 |
226 |
227 |
228 |
229 |
230 | .*:height
231 | http://schemas.android.com/apk/res/android
232 |
233 |
234 | BY_NAME
235 |
236 |
237 |
238 |
239 |
240 |
241 | .*
242 | http://schemas.android.com/apk/res/android
243 |
244 |
245 | BY_NAME
246 |
247 |
248 |
249 |
250 |
251 |
252 | .*
253 | .*
254 |
255 |
256 | BY_NAME
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/copyright/MIT.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2016 Niek Haarman
4 | Copyright (c) 2007 Mockito contributors
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | 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
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Mockito-Kotlin
2 |
3 | [  ](https://maven-badges.herokuapp.com/maven-central/org.mockito.kotlin/mockito-kotlin)
4 | [](https://s01.oss.sonatype.org/content/repositories/snapshots/org/mockito/kotlin/mockito-kotlin/)
5 |
6 | A small library that provides helper functions to work with [Mockito](https://github.com/mockito/mockito) in Kotlin.
7 |
8 | ## Install
9 |
10 | Mockito-Kotlin is available on Maven Central.
11 | For Gradle users, add the following to your `build.gradle`, replacing `x.x.x` with the latest version:
12 |
13 | ```groovy
14 | testImplementation "org.mockito.kotlin:mockito-kotlin:x.x.x"
15 | ```
16 |
17 | ## Example
18 |
19 | A test using Mockito-Kotlin typically looks like the following:
20 |
21 | ```kotlin
22 | @Test
23 | fun doAction_doesSomething(){
24 | /* Given */
25 | val mock = mock {
26 | on { getText() } doReturn "text"
27 | }
28 | val classUnderTest = ClassUnderTest(mock)
29 |
30 | /* When */
31 | classUnderTest.doAction()
32 |
33 | /* Then */
34 | verify(mock).doSomething(any())
35 | }
36 | ```
37 |
38 | For more info and samples, see the [Wiki](https://github.com/mockito/mockito-kotlin/wiki).
39 |
40 | ## Building
41 |
42 | Mockito-Kotlin is built with Gradle.
43 |
44 | - `./gradlew build` builds and tests the project
45 | - `./gradlew publishToMavenLocal` installs the maven artifacts in your local repository
46 | - `./gradlew check` runs the test suite (See Testing below)
47 |
48 | ### Versioning
49 |
50 | Mockito-Kotlin roughly follows SEMVER
51 |
52 | ### Testing
53 |
54 | Mockito-Kotlin's test suite is located in a separate `tests` module,
55 | to allow running the tests using several Kotlin versions whilst still
56 | keeping the base module at a recent version.
57 |
58 | - `./gradlew check` runs the checks including tests.
59 |
60 | Usually it is enough to test only using the default Kotlin versions;
61 | CI will test against multiple versions.
62 | If you want to test using a different Kotlin version locally,
63 | add the `-PtestKotlinVersion=1.2.3` argument to the Gradle invocation while running the tests.
64 |
65 | ### Acknowledgements
66 |
67 | `mockito-kotlin` was created and developed by [nhaarman@](https://github.com/nhaarman) after which the repository was integrated into the official Mockito GitHub organization.
68 | We would like to thank Niek for the original idea and extensive work plus support that went into `mockito-kotlin`.
69 |
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | # Releasing
2 |
3 | 1. Every change on the main development branch is released as -SNAPSHOT version
4 | to Sonatype snapshot repo at https://s01.oss.sonatype.org/content/repositories/snapshots/org/mockito/kotlin/mockito-kotlin.
5 | 2. In order to release a non-snapshot version to Maven Central push an annotated tag, for example:
6 | ```
7 | git tag -a -m "Release 3.4.5" 3.4.5
8 | git push origin 3.4.5
9 | ```
10 | 3. At the moment, you **may not create releases from GitHub Web UI**.
11 | Doing so will make the CI build fail because the CI creates the changelog and posts to GitHub releases.
12 | In the future supporting this would be nice but currently please make releases by pushing from CLI.
13 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "org.gradle.base"
3 | id "org.shipkit.shipkit-changelog" version "1.2.0"
4 | id "org.shipkit.shipkit-github-release" version "1.2.0"
5 | id "org.shipkit.shipkit-auto-version" version "1.2.2"
6 | id "io.github.gradle-nexus.publish-plugin" version "1.3.0"
7 | id "org.jetbrains.kotlin.jvm" version "1.9.20" apply false
8 | id "org.jetbrains.dokka" version "1.9.10" apply false
9 | }
10 |
11 | def test = tasks.register("test") {
12 | dependsOn gradle.includedBuild("tests").task(":test")
13 | }
14 | tasks.named("check") {
15 | dependsOn test
16 | }
17 |
18 | tasks.named("generateChangelog") {
19 | previousRevision = project.ext.'shipkit-auto-version.previous-version'
20 | githubToken = System.getenv("GITHUB_TOKEN")
21 | repository = "mockito/mockito-kotlin"
22 | releaseTag = project.version
23 | }
24 |
25 | tasks.named("githubRelease") {
26 | def genTask = tasks.named("generateChangelog").get()
27 | dependsOn genTask
28 | repository = genTask.repository
29 | changelog = genTask.outputFile
30 | githubToken = System.getenv("GITHUB_TOKEN")
31 | newTagRevision = System.getenv("GITHUB_SHA")
32 | releaseTag = project.version
33 | releaseName = project.version
34 | }
35 |
36 | // Will be used to handle Sonatype staging repositories.
37 | group = 'org.mockito.kotlin'
38 |
39 | nexusPublishing {
40 | repositories {
41 | if (System.getenv("NEXUS_TOKEN_PWD")) {
42 | sonatype {
43 | // Publishing to: https://s01.oss.sonatype.org (faster instance)
44 | nexusUrl = uri("https://s01.oss.sonatype.org/service/local/")
45 | snapshotRepositoryUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
46 |
47 | username = System.getenv("NEXUS_TOKEN_USER")
48 | password = System.getenv("NEXUS_TOKEN_PWD")
49 | }
50 | }
51 | }
52 | }
53 |
54 | def isSnapshot = version.endsWith("-SNAPSHOT")
55 |
56 | if (isSnapshot) {
57 | println "Building a -SNAPSHOT version (Github release and Maven Central tasks are skipped)"
58 | tasks.named("githubRelease") {
59 | //snapshot versions do not produce changelog / Github releases
60 | enabled = false
61 | }
62 | tasks.named("closeAndReleaseStagingRepository") {
63 | //snapshot binaries are available in Sonatype without the need to close the staging repo
64 | enabled = false
65 | }
66 | }
67 |
68 | tasks.register("releaseSummary") {
69 | doLast {
70 | if (isSnapshot) {
71 | println "RELEASE SUMMARY\n" +
72 | " SNAPSHOTS released to: https://s01.oss.sonatype.org/content/repositories/snapshots/org/mockito/kotlin/mockito-kotlin\n" +
73 | " Release to Maven Central: SKIPPED FOR SNAPSHOTS\n" +
74 | " Github releases: SKIPPED FOR SNAPSHOTS"
75 | } else {
76 | println "RELEASE SUMMARY\n" +
77 | " Release to Maven Central (available after delay): https://repo1.maven.org/maven2/org/mockito/kotlin/mockito-kotlin/\n" +
78 | " Github releases: https://github.com/mockito/mockito-kotlin/releases"
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | isRelease=false
2 |
--------------------------------------------------------------------------------
/gradle/publishing.gradle:
--------------------------------------------------------------------------------
1 | //Maven publication plugins & configuration
2 | apply plugin: 'maven-publish'
3 |
4 | task javadocJar(type: Jar, dependsOn: javadoc) {
5 | archiveClassifier = 'javadoc'
6 | from 'build/javadoc'
7 | }
8 |
9 | task sourceJar(type: Jar) {
10 | archiveClassifier = "sources"
11 | from sourceSets.main.allSource
12 | }
13 |
14 | publishing {
15 | publications {
16 | javaLibrary(MavenPublication) {
17 | artifactId 'mockito-kotlin'
18 |
19 | from components.java
20 |
21 | artifact sourceJar
22 | artifact javadocJar
23 |
24 | pom.withXml {
25 | def root = asNode()
26 | root.appendNode('name', 'Mockito-Kotlin')
27 | root.appendNode('description', 'Using Mockito with Kotlin.')
28 | root.appendNode('url', 'https://github.com/mockito/mockito-kotlin')
29 |
30 | def scm = root.appendNode('scm')
31 | scm.appendNode('url', 'scm:git@github.com:mockito/mockito-kotlin.git')
32 |
33 | def licenses = root.appendNode('licenses')
34 | def mitLicense = licenses.appendNode('license')
35 | mitLicense.appendNode('name', 'MIT')
36 |
37 | def developers = root.appendNode('developers')
38 | def nhaarman = developers.appendNode('developer')
39 | nhaarman.appendNode('id', 'nhaarman')
40 | nhaarman.appendNode('name', 'Niek Haarman')
41 | }
42 | }
43 | }
44 |
45 | //useful for testing - running "publish" will create artifacts/pom in a local dir
46 | repositories { maven { url = "$rootProject.buildDir/repo" } }
47 | }
48 |
49 | clean {
50 | delete "$rootProject.buildDir/repo"
51 | }
52 |
53 | // Avoid generation of the module metadata so that we don't have to publish an additional file
54 | // and keep the build logic simple.
55 | tasks.withType(GenerateModuleMetadata) {
56 | enabled = false
57 | }
58 |
59 | //fleshes out problems with Maven pom generation when building
60 | tasks.build.dependsOn('publishJavaLibraryPublicationToMavenLocal')
61 |
62 | apply plugin: 'signing' //https://docs.gradle.org/current/userguide/signing_plugin.html
63 | signing {
64 | if (System.getenv("PGP_KEY")) {
65 | useInMemoryPgpKeys(System.getenv("PGP_KEY"), System.getenv("PGP_PWD"))
66 | sign publishing.publications.javaLibrary
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mockito/mockito-kotlin/f97dd1a8ac1e42c8843a17b6fb51ec1264929b7d/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/mockito-kotlin/build.gradle:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
3 |
4 | plugins {
5 | id "org.jetbrains.kotlin.jvm"
6 | id "org.jetbrains.dokka"
7 | }
8 | apply from: '../gradle/publishing.gradle'
9 |
10 | group = 'org.mockito.kotlin'
11 |
12 | repositories {
13 | mavenCentral()
14 | }
15 |
16 | dependencies {
17 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib"
18 | compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
19 | implementation "org.jetbrains.kotlin:kotlin-reflect:1.9.20"
20 |
21 | api "org.mockito:mockito-core:5.17.0"
22 |
23 | testImplementation 'junit:junit:4.13.2'
24 | testImplementation 'com.nhaarman:expect.kt:1.0.1'
25 |
26 | testImplementation "org.jetbrains.kotlin:kotlin-stdlib"
27 | testImplementation "org.jetbrains.kotlin:kotlin-test"
28 | testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
29 |
30 | testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0"
31 | }
32 |
33 | dokkaHtml.configure {
34 | outputDirectory.set(file("$buildDir/javadoc"))
35 |
36 | dokkaSourceSets {
37 | named("main") {
38 | localDirectory.set(file("src/main/kotlin"))
39 | remoteUrl.set(new URL("https://github.com/nhaarman/mockito-kotlin/tree/master/mockito-kotlin/src/main/kotlin"))
40 | remoteLineSuffix.set("#L")
41 | }
42 | }
43 | }
44 |
45 | tasks.withType(KotlinCompile).configureEach {
46 | compilerOptions {
47 | jvmTarget.set(JvmTarget.JVM_11)
48 | targetCompatibility = "11"
49 | }
50 | }
51 |
52 | javadoc.dependsOn dokkaHtml
53 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/AdditionalMatchers.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2024 Mockito contributors
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * 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
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.mockito.kotlin
26 |
27 | import org.mockito.AdditionalMatchers
28 | import org.mockito.kotlin.internal.createInstance
29 |
30 | /** comparable argument greater than or equal the given value. */
31 | inline fun > geq(value: T): T {
32 | return AdditionalMatchers.geq(value) ?: createInstance()
33 | }
34 |
35 | /** comparable argument greater than or equal to the given value. */
36 | inline fun > leq(value: T): T {
37 | return AdditionalMatchers.leq(value) ?: createInstance()
38 | }
39 |
40 | /** comparable argument greater than the given value. */
41 | inline fun > gt(value: T): T {
42 | return AdditionalMatchers.gt(value) ?: createInstance()
43 | }
44 |
45 | /** comparable argument less than the given value. */
46 | inline fun > lt(value: T): T {
47 | return AdditionalMatchers.lt(value) ?: createInstance()
48 | }
49 |
50 | /** comparable argument equals to the given value according to their compareTo method. */
51 | inline fun > cmpEq(value: T): T {
52 | return AdditionalMatchers.cmpEq(value) ?: createInstance()
53 | }
54 |
55 | /**
56 | * Any array argument that is equal to the given array, i.e. it has to have the same type, length,
57 | * and each element has to be equal.
58 | */
59 | inline fun aryEq(value: Array): Array {
60 | return AdditionalMatchers.aryEq(value) ?: createInstance()
61 | }
62 |
63 | /**
64 | * short array argument that is equal to the given array, i.e. it has to have the same length, and
65 | * each element has to be equal.
66 | */
67 | fun aryEq(value: ShortArray): ShortArray {
68 | return AdditionalMatchers.aryEq(value) ?: createInstance()
69 | }
70 |
71 | /**
72 | * long array argument that is equal to the given array, i.e. it has to have the same length, and
73 | * each element has to be equal.
74 | */
75 | fun aryEq(value: LongArray): LongArray {
76 | return AdditionalMatchers.aryEq(value) ?: createInstance()
77 | }
78 |
79 | /**
80 | * int array argument that is equal to the given array, i.e. it has to have the same length, and
81 | * each element has to be equal.
82 | */
83 | fun aryEq(value: IntArray): IntArray {
84 | return AdditionalMatchers.aryEq(value) ?: createInstance()
85 | }
86 |
87 | /**
88 | * float array argument that is equal to the given array, i.e. it has to have the same length, and
89 | * each element has to be equal.
90 | */
91 | fun aryEq(value: FloatArray): FloatArray {
92 | return AdditionalMatchers.aryEq(value) ?: createInstance()
93 | }
94 |
95 | /**
96 | * double array argument that is equal to the given array, i.e. it has to have the same length, and
97 | * each element has to be equal.
98 | */
99 | fun aryEq(value: DoubleArray): DoubleArray {
100 | return AdditionalMatchers.aryEq(value) ?: createInstance()
101 | }
102 |
103 | /**
104 | * char array argument that is equal to the given array, i.e. it has to have the same length, and
105 | * each element has to be equal.
106 | */
107 | fun aryEq(value: CharArray): CharArray {
108 | return AdditionalMatchers.aryEq(value) ?: createInstance()
109 | }
110 |
111 | /**
112 | * byte array argument that is equal to the given array, i.e. it has to have the same length, and
113 | * each element has to be equal.
114 | */
115 | fun aryEq(value: ByteArray): ByteArray {
116 | return AdditionalMatchers.aryEq(value) ?: createInstance()
117 | }
118 |
119 | /**
120 | * boolean array argument that is equal to the given array, i.e. it has to have the same length, and
121 | * each element has to be equal.
122 | */
123 | fun aryEq(value: BooleanArray): BooleanArray {
124 | return AdditionalMatchers.aryEq(value) ?: createInstance()
125 | }
126 |
127 | /** String argument that contains a substring that matches the given regular expression. */
128 | fun find(regex: Regex): String {
129 | return AdditionalMatchers.find(regex.pattern) ?: ""
130 | }
131 |
132 | /** argument that matches both given argument matchers. */
133 | inline fun and(left: T, right: T): T {
134 | return AdditionalMatchers.and(left, right) ?: createInstance()
135 | }
136 |
137 | /** argument that matches both given argument matchers. */
138 | inline fun or(left: T, right: T): T {
139 | return AdditionalMatchers.or(left, right) ?: createInstance()
140 | }
141 |
142 | /** argument that does not match the given argument matcher. */
143 | inline fun not(matcher: T): T {
144 | return AdditionalMatchers.not(matcher) ?: createInstance()
145 | }
146 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/ArgumentCaptor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.kotlin.internal.createInstance
29 | import org.mockito.ArgumentCaptor
30 | import java.lang.reflect.Array
31 | import kotlin.reflect.KClass
32 |
33 | /**
34 | * Creates a [KArgumentCaptor] for given type.
35 | */
36 | inline fun argumentCaptor(): KArgumentCaptor {
37 | return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
38 | }
39 |
40 | /**
41 | * Creates 2 [KArgumentCaptor]s for given types.
42 | */
43 | inline fun argumentCaptor(
44 | a: KClass = A::class,
45 | b: KClass = B::class
46 | ): Pair, KArgumentCaptor> {
47 | return Pair(
48 | KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
49 | KArgumentCaptor(ArgumentCaptor.forClass(b.java), b)
50 | )
51 | }
52 |
53 | /**
54 | * Creates 3 [KArgumentCaptor]s for given types.
55 | */
56 | inline fun argumentCaptor(
57 | a: KClass = A::class,
58 | b: KClass = B::class,
59 | c: KClass = C::class
60 | ): Triple, KArgumentCaptor, KArgumentCaptor> {
61 | return Triple(
62 | KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
63 | KArgumentCaptor(ArgumentCaptor.forClass(b.java), b),
64 | KArgumentCaptor(ArgumentCaptor.forClass(c.java), c)
65 | )
66 | }
67 |
68 | class ArgumentCaptorHolder4(
69 | val first: A,
70 | val second: B,
71 | val third: C,
72 | val fourth: D
73 | ) {
74 |
75 | operator fun component1() = first
76 | operator fun component2() = second
77 | operator fun component3() = third
78 | operator fun component4() = fourth
79 | }
80 |
81 | class ArgumentCaptorHolder5(
82 | val first: A,
83 | val second: B,
84 | val third: C,
85 | val fourth: D,
86 | val fifth: E
87 | ) {
88 |
89 | operator fun component1() = first
90 | operator fun component2() = second
91 | operator fun component3() = third
92 | operator fun component4() = fourth
93 | operator fun component5() = fifth
94 | }
95 |
96 | /**
97 | * Creates 4 [KArgumentCaptor]s for given types.
98 | */
99 | inline fun argumentCaptor(
100 | a: KClass = A::class,
101 | b: KClass = B::class,
102 | c: KClass = C::class,
103 | d: KClass = D::class
104 | ): ArgumentCaptorHolder4, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> {
105 | return ArgumentCaptorHolder4(
106 | KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
107 | KArgumentCaptor(ArgumentCaptor.forClass(b.java), b),
108 | KArgumentCaptor(ArgumentCaptor.forClass(c.java), c),
109 | KArgumentCaptor(ArgumentCaptor.forClass(d.java), d)
110 | )
111 | }
112 |
113 | /**
114 | * Creates 4 [KArgumentCaptor]s for given types.
115 | */
116 | inline fun argumentCaptor(
117 | a: KClass = A::class,
118 | b: KClass = B::class,
119 | c: KClass = C::class,
120 | d: KClass = D::class,
121 | e: KClass = E::class
122 | ): ArgumentCaptorHolder5, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor, KArgumentCaptor> {
123 | return ArgumentCaptorHolder5(
124 | KArgumentCaptor(ArgumentCaptor.forClass(a.java), a),
125 | KArgumentCaptor(ArgumentCaptor.forClass(b.java), b),
126 | KArgumentCaptor(ArgumentCaptor.forClass(c.java), c),
127 | KArgumentCaptor(ArgumentCaptor.forClass(d.java), d),
128 | KArgumentCaptor(ArgumentCaptor.forClass(e.java), e)
129 | )
130 | }
131 |
132 | /**
133 | * Creates a [KArgumentCaptor] for given type, taking in a lambda to allow fast verification.
134 | */
135 | inline fun argumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor {
136 | return argumentCaptor().apply(f)
137 | }
138 |
139 | /**
140 | * Creates a [KArgumentCaptor] for given nullable type.
141 | */
142 | inline fun nullableArgumentCaptor(): KArgumentCaptor {
143 | return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
144 | }
145 |
146 | /**
147 | * Creates a [KArgumentCaptor] for given nullable type, taking in a lambda to allow fast verification.
148 | */
149 | inline fun nullableArgumentCaptor(f: KArgumentCaptor.() -> Unit): KArgumentCaptor {
150 | return nullableArgumentCaptor().apply(f)
151 | }
152 |
153 | /**
154 | * Alias for [ArgumentCaptor.capture].
155 | */
156 | inline fun capture(captor: ArgumentCaptor): T {
157 | return captor.capture() ?: createInstance()
158 | }
159 |
160 | class KArgumentCaptor(
161 | private val captor: ArgumentCaptor,
162 | private val tClass: KClass<*>
163 | ) {
164 |
165 | /**
166 | * The first captured value of the argument.
167 | * @throws IndexOutOfBoundsException if the value is not available.
168 | */
169 | val firstValue: T
170 | get() = captor.firstValue
171 |
172 | /**
173 | * The second captured value of the argument.
174 | * @throws IndexOutOfBoundsException if the value is not available.
175 | */
176 | val secondValue: T
177 | get() = captor.secondValue
178 |
179 | /**
180 | * The third captured value of the argument.
181 | * @throws IndexOutOfBoundsException if the value is not available.
182 | */
183 | val thirdValue: T
184 | get() = captor.thirdValue
185 |
186 | /**
187 | * The last captured value of the argument.
188 | * @throws IndexOutOfBoundsException if the value is not available.
189 | */
190 | val lastValue: T
191 | get() = captor.lastValue
192 |
193 | /**
194 | * The *only* captured value of the argument,
195 | * or throws an exception if no value or more than one value was captured.
196 | */
197 | val singleValue: T
198 | get() = captor.singleValue
199 |
200 | val allValues: List
201 | get() = captor.allValues
202 |
203 | @Suppress("UNCHECKED_CAST")
204 | fun capture(): T {
205 | // Special handling for arrays to make it work for varargs
206 | // In Kotlin we want have to capture vararg like this `verify(m).methodName(*captor.capture())` to make the types work
207 | // If we return null for array types, the spread `*` operator will fail with NPE
208 | // If we return empty array, it will fail in MatchersBinder.validateMatchers
209 | // In Java, `captor.capture` returns null and so the method is called with `[null]`
210 | // In Kotlin, we have to create `[null]` explicitly.
211 | // This code-path is applied for non-vararg array arguments as well, but it seems to work fine.
212 | return captor.capture() ?: if (tClass.java.isArray) {
213 | singleElementArray()
214 | } else {
215 | createInstance(tClass)
216 | } as T
217 | }
218 |
219 | private fun singleElementArray(): Any? = Array.newInstance(tClass.java.componentType, 1)
220 | }
221 |
222 | val ArgumentCaptor.firstValue: T
223 | get() = allValues[0]
224 |
225 | val ArgumentCaptor.secondValue: T
226 | get() = allValues[1]
227 |
228 | val ArgumentCaptor.thirdValue: T
229 | get() = allValues[2]
230 |
231 | val ArgumentCaptor.lastValue: T
232 | get() = allValues.last()
233 |
234 | val ArgumentCaptor.singleValue: T
235 | get() = allValues.single()
236 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/BDDMockito.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import kotlinx.coroutines.CoroutineScope
29 | import kotlinx.coroutines.runBlocking
30 | import org.mockito.BDDMockito
31 | import org.mockito.BDDMockito.BDDMyOngoingStubbing
32 | import org.mockito.BDDMockito.Then
33 | import org.mockito.invocation.InvocationOnMock
34 | import org.mockito.kotlin.internal.SuspendableAnswer
35 | import org.mockito.stubbing.Answer
36 | import kotlin.reflect.KClass
37 |
38 | /**
39 | * Alias for [BDDMockito.given].
40 | */
41 | fun given(methodCall: T): BDDMockito.BDDMyOngoingStubbing {
42 | return BDDMockito.given(methodCall)
43 | }
44 |
45 | /**
46 | * Alias for [BDDMockito.given] with a lambda.
47 | */
48 | fun given(methodCall: () -> T): BDDMyOngoingStubbing {
49 | return given(methodCall())
50 | }
51 |
52 | /**
53 | * Alias for [BDDMockito.given] with a suspending lambda
54 | *
55 | * Warning: Only last method call can be stubbed in the function.
56 | * other method calls are ignored!
57 | */
58 | fun givenBlocking(methodCall: suspend CoroutineScope.() -> T): BDDMockito.BDDMyOngoingStubbing {
59 | return runBlocking { BDDMockito.given(methodCall()) }
60 | }
61 |
62 | /**
63 | * Alias for [BDDMockito.then].
64 | */
65 | fun then(mock: T): BDDMockito.Then {
66 | return BDDMockito.then(mock)
67 | }
68 |
69 | /**
70 | * Alias for [Then.should], with suspending lambda.
71 | */
72 | fun Then.shouldBlocking(f: suspend T.() -> R): R {
73 | val m = should()
74 | return runBlocking { m.f() }
75 | }
76 |
77 | /**
78 | * Alias for [BDDMyOngoingStubbing.will]
79 | * */
80 | infix fun BDDMyOngoingStubbing.will(value: Answer): BDDMockito.BDDMyOngoingStubbing {
81 | return will(value)
82 | }
83 |
84 | /**
85 | * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a lambda.
86 | */
87 | infix fun BDDMyOngoingStubbing.willAnswer(value: (InvocationOnMock) -> T?): BDDMockito.BDDMyOngoingStubbing {
88 | return willAnswer { value(it) }
89 | }
90 |
91 | /**
92 | * Alias for [BBDMyOngoingStubbing.willAnswer], accepting a suspend lambda.
93 | */
94 | infix fun BDDMyOngoingStubbing.willSuspendableAnswer(value: suspend (InvocationOnMock) -> T?): BDDMockito.BDDMyOngoingStubbing {
95 | return willAnswer(SuspendableAnswer(value))
96 | }
97 |
98 | /**
99 | * Alias for [BBDMyOngoingStubbing.willReturn].
100 | */
101 | infix fun BDDMyOngoingStubbing.willReturn(value: () -> T): BDDMockito.BDDMyOngoingStubbing {
102 | return willReturn(value())
103 | }
104 |
105 | /**
106 | * Alias for [BBDMyOngoingStubbing.willThrow].
107 | */
108 | infix fun BDDMyOngoingStubbing.willThrow(value: () -> Throwable): BDDMockito.BDDMyOngoingStubbing {
109 | return willThrow(value())
110 | }
111 |
112 | /**
113 | * Sets a Throwable type to be thrown when the method is called.
114 | *
115 | * Alias for [BDDMyOngoingStubbing.willThrow]
116 | */
117 | infix fun BDDMyOngoingStubbing.willThrow(t: KClass): BDDMyOngoingStubbing {
118 | return willThrow(t.java)
119 | }
120 |
121 | /**
122 | * Sets Throwable classes to be thrown when the method is called.
123 | *
124 | * Alias for [BDDMyOngoingStubbing.willThrow]
125 | */
126 | fun BDDMyOngoingStubbing.willThrow(
127 | t: KClass,
128 | vararg ts: KClass
129 | ): BDDMyOngoingStubbing {
130 | return willThrow(t.java, *ts.map { it.java }.toTypedArray())
131 | }
132 |
133 | /**
134 | * Sets consecutive return values to be returned when the method is called.
135 | * Same as [BDDMyOngoingStubbing.willReturn], but accepts list instead of varargs.
136 | */
137 | inline infix fun BDDMyOngoingStubbing.willReturnConsecutively(ts: List): BDDMyOngoingStubbing {
138 | return willReturn(
139 | ts[0],
140 | *ts.drop(1).toTypedArray()
141 | )
142 | }
143 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KInOrder.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.InOrder
29 | import org.mockito.verification.VerificationMode
30 |
31 | interface KInOrder : InOrder {
32 | /**
33 | * Verifies certain suspending behavior happened once in order.
34 | *
35 | * Warning: Only one method call can be verified in the function.
36 | * Subsequent method calls are ignored!
37 | */
38 | fun verifyBlocking(mock: T, f: suspend T.() -> Unit)
39 |
40 | /**
41 | * Verifies certain suspending behavior happened at least once / exact number of times / never in order.
42 | *
43 | * Warning: Only one method call can be verified in the function.
44 | * Subsequent method calls are ignored!
45 | */
46 | fun verifyBlocking(mock: T, mode: VerificationMode, f: suspend T.() -> Unit)
47 | }
48 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KInvocationOnMock.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.invocation.InvocationOnMock
29 |
30 | class KInvocationOnMock(
31 | private val invocationOnMock: InvocationOnMock
32 | ) : InvocationOnMock by invocationOnMock {
33 |
34 | operator fun component1(): T = invocationOnMock.getArgument(0)
35 | operator fun component2(): T = invocationOnMock.getArgument(1)
36 | operator fun component3(): T = invocationOnMock.getArgument(2)
37 | operator fun component4(): T = invocationOnMock.getArgument(3)
38 | operator fun component5(): T = invocationOnMock.getArgument(4)
39 | }
40 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/KStubbing.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.kotlin.internal.createInstance
29 | import kotlinx.coroutines.runBlocking
30 | import org.mockito.Mockito
31 | import org.mockito.exceptions.misusing.NotAMockException
32 | import org.mockito.stubbing.OngoingStubbing
33 | import org.mockito.stubbing.Stubber
34 | import kotlin.reflect.KClass
35 |
36 | inline fun stubbing(
37 | mock: T,
38 | stubbing: KStubbing.(T) -> Unit
39 | ) {
40 | KStubbing(mock).stubbing(mock)
41 | }
42 |
43 | inline fun T.stub(stubbing: KStubbing.(T) -> Unit): T {
44 | return apply { KStubbing(this).stubbing(this) }
45 | }
46 |
47 | class KStubbing(val mock: T) {
48 | init {
49 | if (!mockingDetails(mock).isMock) throw NotAMockException("Stubbing target is not a mock!")
50 | }
51 |
52 | fun on(methodCall: R): OngoingStubbing = Mockito.`when`(methodCall)
53 |
54 | fun onGeneric(methodCall: T.() -> R?, c: KClass): OngoingStubbing {
55 | val r = try {
56 | mock.methodCall()
57 | } catch (e: NullPointerException) {
58 | // An NPE may be thrown by the Kotlin type system when the MockMethodInterceptor returns a
59 | // null value for a non-nullable generic type.
60 | // We catch this NPE to return a valid instance.
61 | // The Mockito state has already been modified at this point to reflect
62 | // the wanted changes.
63 | createInstance(c)
64 | }
65 | return Mockito.`when`(r)
66 | }
67 |
68 | inline fun onGeneric(noinline methodCall: T.() -> R?): OngoingStubbing {
69 | return onGeneric(methodCall, R::class)
70 | }
71 |
72 | fun on(methodCall: T.() -> R): OngoingStubbing {
73 | return try {
74 | Mockito.`when`(mock.methodCall())
75 | } catch (e: NullPointerException) {
76 | throw MockitoKotlinException(
77 | "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.",
78 | e
79 | )
80 | }
81 | }
82 |
83 | fun KStubbing.onBlocking(
84 | m: suspend T.() -> R
85 | ): OngoingStubbing {
86 | return runBlocking { Mockito.`when`(mock.m()) }
87 | }
88 |
89 | fun Stubber.on(methodCall: T.() -> Unit) {
90 | this.`when`(mock).methodCall()
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/LenientStubber.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.stubbing.LenientStubber
29 | import org.mockito.stubbing.OngoingStubbing
30 |
31 | inline fun LenientStubber.whenever(methodCall: T): OngoingStubbing {
32 | return `when`(methodCall)
33 | }
34 |
35 | inline fun LenientStubber.whenever(methodCall: () -> T): OngoingStubbing {
36 | return whenever(methodCall())
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Matchers.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.ArgumentMatcher
29 | import org.mockito.ArgumentMatchers
30 | import org.mockito.kotlin.internal.createInstance
31 | import kotlin.reflect.KClass
32 |
33 | /** Object argument that is equal to the given value. */
34 | fun eq(value: T): T {
35 | return ArgumentMatchers.eq(value) ?: value
36 | }
37 |
38 | /** Object argument that is the same as the given value. */
39 | fun same(value: T): T {
40 | return ArgumentMatchers.same(value) ?: value
41 | }
42 |
43 | /** Matches any object, excluding nulls. */
44 | inline fun any(): T {
45 | if(T::class.isValue)
46 | return anyValueClass()
47 |
48 | return ArgumentMatchers.any(T::class.java) ?: createInstance()
49 | }
50 |
51 | /** Matches anything, including nulls. */
52 | inline fun anyOrNull(): T {
53 | return ArgumentMatchers.any() ?: createInstance()
54 | }
55 |
56 | /** Matches any vararg object, including nulls. */
57 | inline fun anyVararg(): T {
58 | return anyVararg(T::class)
59 | }
60 |
61 | fun anyVararg(clazz: KClass): T {
62 | return ArgumentMatchers.argThat(VarargMatcher(clazz.java)) ?: createInstance(clazz)
63 | }
64 |
65 | private class VarargMatcher(private val clazz: Class) : ArgumentMatcher {
66 | override fun matches(t: T): Boolean = true
67 |
68 | // In Java >= 12 you can do clazz.arrayClass()
69 | override fun type(): Class<*> = java.lang.reflect.Array.newInstance(clazz, 0).javaClass
70 | }
71 |
72 | /** Matches any array of type T. */
73 | inline fun anyArray(): Array {
74 | return ArgumentMatchers.any(Array::class.java) ?: arrayOf()
75 | }
76 |
77 | /** Matches any Kotlin value class with the same boxed type by taking its boxed type. */
78 | inline fun anyValueClass(): T {
79 | require(T::class.isValue) {
80 | "${T::class.qualifiedName} is not a value class."
81 | }
82 |
83 | val boxImpls = T::class.java.declaredMethods.filter { it.name == "box-impl" && it.parameterCount == 1 }
84 | require(boxImpls.size == 1) // Sanity check
85 |
86 | val boxImpl = boxImpls.first()
87 | val boxedType = boxImpl.parameters[0].type
88 |
89 | return boxImpl.invoke(null, ArgumentMatchers.any(boxedType)) as T
90 | }
91 |
92 | /**
93 | * Creates a custom argument matcher.
94 | * `null` values will never evaluate to `true`.
95 | *
96 | * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate.
97 | */
98 | inline fun argThat(noinline predicate: T.() -> Boolean): T {
99 | return ArgumentMatchers.argThat { arg: T? -> arg?.predicate() ?: false } ?: createInstance(
100 | T::class
101 | )
102 | }
103 |
104 | /**
105 | * Registers a custom ArgumentMatcher. The original Mockito function registers the matcher and returns null,
106 | * here the required type is returned.
107 | *
108 | * @param matcher The ArgumentMatcher on [T] to be registered.
109 | */
110 | inline fun argThat(matcher: ArgumentMatcher): T {
111 | return ArgumentMatchers.argThat(matcher) ?: createInstance()
112 | }
113 |
114 | /**
115 | * Alias for [argThat].
116 | *
117 | * Creates a custom argument matcher.
118 | * `null` values will never evaluate to `true`.
119 | *
120 | * @param predicate An extension function on [T] that returns `true` when a [T] matches the predicate.
121 | */
122 | inline fun argForWhich(noinline predicate: T.() -> Boolean): T {
123 | return argThat(predicate)
124 | }
125 |
126 | /**
127 | * Creates a custom argument matcher.
128 | * `null` values will never evaluate to `true`.
129 | *
130 | * @param predicate A function that returns `true` when given [T] matches the predicate.
131 | */
132 | inline fun argWhere(noinline predicate: (T) -> Boolean): T {
133 | return argThat(predicate)
134 | }
135 |
136 | /**
137 | * Argument that implements the given class.
138 | */
139 | inline fun isA(): T {
140 | return ArgumentMatchers.isA(T::class.java) ?: createInstance()
141 | }
142 |
143 | /**
144 | * `null` argument.
145 | */
146 | fun isNull(): T? = ArgumentMatchers.isNull()
147 |
148 | /**
149 | * Not `null` argument.
150 | */
151 | fun isNotNull(): T? {
152 | return ArgumentMatchers.isNotNull()
153 | }
154 |
155 | /**
156 | * Not `null` argument.
157 | */
158 | fun notNull(): T? {
159 | return ArgumentMatchers.notNull()
160 | }
161 |
162 | /**
163 | * Object argument that is reflection-equal to the given value with support for excluding
164 | * selected fields from a class.
165 | */
166 | inline fun refEq(value: T, vararg excludeFields: String): T {
167 | return ArgumentMatchers.refEq(value, *excludeFields) ?: createInstance()
168 | }
169 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mocking.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.Incubating
29 | import org.mockito.MockSettings
30 | import org.mockito.Mockito
31 | import org.mockito.listeners.InvocationListener
32 | import org.mockito.mock.SerializableMode
33 | import org.mockito.quality.Strictness
34 | import org.mockito.stubbing.Answer
35 | import kotlin.DeprecationLevel.ERROR
36 | import kotlin.reflect.KClass
37 |
38 | /**
39 | * Creates a mock for [T].
40 | *
41 | * @param extraInterfaces Specifies extra interfaces the mock should implement.
42 | * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors.
43 | * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks.
44 | * @param defaultAnswer Specifies default answers to interactions.
45 | * @param serializable Configures the mock to be serializable.
46 | * @param serializableMode Configures the mock to be serializable with a specific serializable mode.
47 | * @param verboseLogging Enables real-time logging of method invocations on this mock.
48 | * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called.
49 | * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations.
50 | * @param useConstructor Mockito attempts to use constructor when creating instance of the mock.
51 | * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor].
52 | * @param lenient Lenient mocks bypass "strict stubbing" validation.
53 | */
54 | inline fun mock(
55 | extraInterfaces: Array>? = null,
56 | name: String? = null,
57 | spiedInstance: Any? = null,
58 | defaultAnswer: Answer? = null,
59 | serializable: Boolean = false,
60 | serializableMode: SerializableMode? = null,
61 | verboseLogging: Boolean = false,
62 | invocationListeners: Array? = null,
63 | stubOnly: Boolean = false,
64 | @Incubating useConstructor: UseConstructor? = null,
65 | @Incubating outerInstance: Any? = null,
66 | @Incubating lenient: Boolean = false
67 | ): T {
68 | return Mockito.mock(
69 | T::class.java,
70 | withSettings(
71 | extraInterfaces = extraInterfaces,
72 | name = name,
73 | spiedInstance = spiedInstance,
74 | defaultAnswer = defaultAnswer,
75 | serializable = serializable,
76 | serializableMode = serializableMode,
77 | verboseLogging = verboseLogging,
78 | invocationListeners = invocationListeners,
79 | stubOnly = stubOnly,
80 | useConstructor = useConstructor,
81 | outerInstance = outerInstance,
82 | lenient = lenient
83 | )
84 | )!!
85 | }
86 |
87 | /**
88 | * Creates a mock for [T], allowing for immediate stubbing.
89 | *
90 | * @param extraInterfaces Specifies extra interfaces the mock should implement.
91 | * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors.
92 | * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks.
93 | * @param defaultAnswer Specifies default answers to interactions.
94 | * @param serializable Configures the mock to be serializable.
95 | * @param serializableMode Configures the mock to be serializable with a specific serializable mode.
96 | * @param verboseLogging Enables real-time logging of method invocations on this mock.
97 | * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called.
98 | * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations.
99 | * @param useConstructor Mockito attempts to use constructor when creating instance of the mock.
100 | * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor].
101 | * @param lenient Lenient mocks bypass "strict stubbing" validation.
102 | */
103 | inline fun mock(
104 | extraInterfaces: Array>? = null,
105 | name: String? = null,
106 | spiedInstance: Any? = null,
107 | defaultAnswer: Answer? = null,
108 | serializable: Boolean = false,
109 | serializableMode: SerializableMode? = null,
110 | verboseLogging: Boolean = false,
111 | invocationListeners: Array? = null,
112 | stubOnly: Boolean = false,
113 | @Incubating useConstructor: UseConstructor? = null,
114 | @Incubating outerInstance: Any? = null,
115 | @Incubating lenient: Boolean = false,
116 | stubbing: KStubbing.(T) -> Unit
117 | ): T {
118 | return Mockito.mock(
119 | T::class.java,
120 | withSettings(
121 | extraInterfaces = extraInterfaces,
122 | name = name,
123 | spiedInstance = spiedInstance,
124 | defaultAnswer = defaultAnswer,
125 | serializable = serializable,
126 | serializableMode = serializableMode,
127 | verboseLogging = verboseLogging,
128 | invocationListeners = invocationListeners,
129 | stubOnly = stubOnly,
130 | useConstructor = useConstructor,
131 | outerInstance = outerInstance,
132 | lenient = lenient
133 | )
134 | ).apply { KStubbing(this).stubbing(this) }!!
135 | }
136 |
137 | /**
138 | * Allows mock creation with additional mock settings.
139 | * See [MockSettings].
140 | *
141 | * @param extraInterfaces Specifies extra interfaces the mock should implement.
142 | * @param name Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors.
143 | * @param spiedInstance Specifies the instance to spy on. Makes sense only for spies/partial mocks.
144 | * @param defaultAnswer Specifies default answers to interactions.
145 | * @param serializable Configures the mock to be serializable.
146 | * @param serializableMode Configures the mock to be serializable with a specific serializable mode.
147 | * @param verboseLogging Enables real-time logging of method invocations on this mock.
148 | * @param invocationListeners Registers a listener for method invocations on this mock. The listener is notified every time a method on this mock is called.
149 | * @param stubOnly A stub-only mock does not record method invocations, thus saving memory but disallowing verification of invocations.
150 | * @param useConstructor Mockito attempts to use constructor when creating instance of the mock.
151 | * @param outerInstance Makes it possible to mock non-static inner classes in conjunction with [useConstructor].
152 | * @param lenient Lenient mocks bypass "strict stubbing" validation.
153 | */
154 | fun withSettings(
155 | extraInterfaces: Array>? = null,
156 | name: String? = null,
157 | spiedInstance: Any? = null,
158 | defaultAnswer: Answer? = null,
159 | serializable: Boolean = false,
160 | serializableMode: SerializableMode? = null,
161 | verboseLogging: Boolean = false,
162 | invocationListeners: Array? = null,
163 | stubOnly: Boolean = false,
164 | @Incubating useConstructor: UseConstructor? = null,
165 | @Incubating outerInstance: Any? = null,
166 | @Incubating lenient: Boolean = false
167 | ): MockSettings = Mockito.withSettings().apply {
168 | extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) }
169 | name?.let { name(it) }
170 | spiedInstance?.let { spiedInstance(it) }
171 | defaultAnswer?.let { defaultAnswer(it) }
172 | if (serializable) serializable()
173 | serializableMode?.let { serializable(it) }
174 | if (verboseLogging) verboseLogging()
175 | invocationListeners?.let { invocationListeners(*it) }
176 | if (stubOnly) stubOnly()
177 | useConstructor?.let { useConstructor(*it.args) }
178 | outerInstance?.let { outerInstance(it) }
179 | if (lenient) strictness(Strictness.LENIENT)
180 | }
181 |
182 | class UseConstructor private constructor(val args: Array) {
183 |
184 | companion object {
185 |
186 | /** Invokes the parameterless constructor. */
187 | fun parameterless() = UseConstructor(emptyArray())
188 |
189 | /** Invokes a constructor with given arguments. */
190 | fun withArguments(vararg arguments: Any): UseConstructor {
191 | return UseConstructor(arguments.asList().toTypedArray())
192 | }
193 | }
194 | }
195 |
196 | @Deprecated(
197 | "Use mock() with optional arguments instead.",
198 | ReplaceWith("mock(defaultAnswer = a)"),
199 | level = ERROR
200 | )
201 | inline fun mock(a: Answer): T = mock(defaultAnswer = a)
202 |
203 | @Deprecated(
204 | "Use mock() with optional arguments instead.",
205 | ReplaceWith("mock(name = s)"),
206 | level = ERROR
207 | )
208 | inline fun mock(s: String): T = mock(name = s)
209 |
210 | @Suppress("DeprecatedCallableAddReplaceWith")
211 | @Deprecated("Use mock() with optional arguments instead.", level = ERROR)
212 | inline fun mock(s: MockSettings): T = Mockito.mock(T::class.java, s)!!
213 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Mockito.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.MockingDetails
29 | import org.mockito.Mockito
30 |
31 | fun validateMockitoUsage() {
32 | Mockito.validateMockitoUsage()
33 | }
34 |
35 | fun reset(vararg mocks: T) {
36 | Mockito.reset(*mocks)
37 | }
38 |
39 | fun mockingDetails(toInspect: Any): MockingDetails {
40 | return Mockito.mockingDetails(toInspect)!!
41 | }
42 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/MockitoKotlinException.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | class MockitoKotlinException(message: String?, cause: Throwable?) : RuntimeException(message, cause)
29 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/OngoingStubbing.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import kotlinx.coroutines.CoroutineScope
29 | import kotlinx.coroutines.runBlocking
30 | import org.mockito.Mockito
31 | import org.mockito.kotlin.internal.KAnswer
32 | import org.mockito.kotlin.internal.SuspendableAnswer
33 | import org.mockito.stubbing.Answer
34 | import org.mockito.stubbing.OngoingStubbing
35 | import kotlin.reflect.KClass
36 |
37 | /**
38 | * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called.
39 | *
40 | * Alias for [Mockito.when].
41 | */
42 | @Suppress("NOTHING_TO_INLINE")
43 | inline fun whenever(methodCall: T): OngoingStubbing {
44 | return Mockito.`when`(methodCall)!!
45 | }
46 |
47 | /**
48 | * Enables stubbing suspending methods. Use it when you want the mock to return particular value when particular suspending method is called.
49 | *
50 | * Warning: Only one method call can be stubbed in the function.
51 | * other method calls are ignored!
52 | */
53 | fun wheneverBlocking(methodCall: suspend CoroutineScope.() -> T): OngoingStubbing {
54 | return runBlocking { Mockito.`when`(methodCall()) }
55 | }
56 |
57 | /**
58 | * Sets a return value to be returned when the method is called.
59 | *
60 | * Alias for [OngoingStubbing.thenReturn].
61 | */
62 | infix fun OngoingStubbing.doReturn(t: T): OngoingStubbing {
63 | return thenReturn(t)
64 | }
65 |
66 | /**
67 | * Sets consecutive return values to be returned when the method is called.
68 | *
69 | * Alias for [OngoingStubbing.thenReturn].
70 | */
71 | fun OngoingStubbing.doReturn(t: T, vararg ts: T): OngoingStubbing {
72 | return thenReturn(t, *ts)
73 | }
74 |
75 | /**
76 | * Sets consecutive return values to be returned when the method is called.
77 | */
78 | inline infix fun OngoingStubbing.doReturnConsecutively(ts: List): OngoingStubbing {
79 | return thenReturn(
80 | ts[0],
81 | *ts.drop(1).toTypedArray()
82 | )
83 | }
84 |
85 | /**
86 | * Sets Throwable objects to be thrown when the method is called.
87 | *
88 | * Alias for [OngoingStubbing.thenThrow].
89 | */
90 | infix fun OngoingStubbing.doThrow(t: Throwable): OngoingStubbing {
91 | return thenThrow(t)
92 | }
93 |
94 | /**
95 | * Sets Throwable objects to be thrown when the method is called.
96 | *
97 | * Alias for [OngoingStubbing.doThrow].
98 | */
99 | fun OngoingStubbing.doThrow(
100 | t: Throwable,
101 | vararg ts: Throwable
102 | ): OngoingStubbing {
103 | return thenThrow(t, *ts)
104 | }
105 |
106 | /**
107 | * Sets a Throwable type to be thrown when the method is called.
108 | */
109 | infix fun OngoingStubbing.doThrow(t: KClass): OngoingStubbing {
110 | return thenThrow(t.java)
111 | }
112 |
113 | /**
114 | * Sets Throwable classes to be thrown when the method is called.
115 | */
116 | fun OngoingStubbing.doThrow(
117 | t: KClass,
118 | vararg ts: KClass
119 | ): OngoingStubbing {
120 | return thenThrow(t.java, *ts.map { it.java }.toTypedArray())
121 | }
122 |
123 | /**
124 | * Sets a generic Answer for the method.
125 | *
126 | * Alias for [OngoingStubbing.thenAnswer].
127 | */
128 | infix fun OngoingStubbing.doAnswer(answer: Answer<*>): OngoingStubbing {
129 | return thenAnswer(answer)
130 | }
131 |
132 | /**
133 | * Sets a generic Answer for the method using a lambda.
134 | */
135 | infix fun OngoingStubbing.doAnswer(answer: (KInvocationOnMock) -> T?): OngoingStubbing {
136 | return thenAnswer(KAnswer(answer))
137 | }
138 |
139 | infix fun OngoingStubbing.doSuspendableAnswer(answer: suspend (KInvocationOnMock) -> T?): OngoingStubbing {
140 | return thenAnswer(SuspendableAnswer(answer))
141 | }
142 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Spying.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.Mockito
29 |
30 | /**
31 | * Creates a spy of the real object.
32 | * The spy calls real methods unless they are stubbed.
33 | */
34 | inline fun spy(): T {
35 | return Mockito.spy(T::class.java)!!
36 | }
37 |
38 | /**
39 | * Creates a spy of the real object, allowing for immediate stubbing.
40 | * The spy calls real methods unless they are stubbed.
41 | */
42 | inline fun spy(stubbing: KStubbing.(T) -> Unit): T {
43 | return Mockito.spy(T::class.java)
44 | .apply { KStubbing(this).stubbing(this) }!!
45 | }
46 |
47 | /**
48 | * Creates a spy of the real object. The spy calls real methods unless they are stubbed.
49 | */
50 | fun spy(value: T): T {
51 | return Mockito.spy(value)!!
52 | }
53 |
54 | /**
55 | * Creates a spy of the real object, allowing for immediate stubbing.
56 | * The spy calls real methods unless they are stubbed.
57 | */
58 | inline fun spy(value: T, stubbing: KStubbing.(T) -> Unit): T {
59 | return spy(value)
60 | .apply { KStubbing(this).stubbing(this) }
61 | }
62 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Stubber.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import kotlinx.coroutines.runBlocking
29 | import org.mockito.Mockito
30 | import org.mockito.invocation.InvocationOnMock
31 | import org.mockito.kotlin.internal.SuspendableAnswer
32 | import org.mockito.stubbing.OngoingStubbing
33 | import org.mockito.stubbing.Stubber
34 | import kotlin.reflect.KClass
35 |
36 | fun doAnswer(answer: (InvocationOnMock) -> T?): Stubber {
37 | return Mockito.doAnswer { answer(it) }!!
38 | }
39 |
40 | fun doSuspendableAnswer(answer: suspend (KInvocationOnMock) -> T?): Stubber {
41 | return Mockito.doAnswer(SuspendableAnswer(answer))
42 | }
43 |
44 | fun doCallRealMethod(): Stubber {
45 | return Mockito.doCallRealMethod()!!
46 | }
47 |
48 | fun doNothing(): Stubber {
49 | return Mockito.doNothing()!!
50 | }
51 |
52 | fun doReturn(value: Any?): Stubber {
53 | return Mockito.doReturn(value)!!
54 | }
55 |
56 | fun doReturn(toBeReturned: Any?, vararg toBeReturnedNext: Any?): Stubber {
57 | return Mockito.doReturn(
58 | toBeReturned,
59 | *toBeReturnedNext
60 | )!!
61 | }
62 |
63 | fun doThrow(toBeThrown: KClass): Stubber {
64 | return Mockito.doThrow(toBeThrown.java)!!
65 | }
66 |
67 | fun doThrow(vararg toBeThrown: Throwable): Stubber {
68 | return Mockito.doThrow(*toBeThrown)!!
69 | }
70 |
71 | fun Stubber.whenever(mock: T) = `when`(mock)
72 |
73 | /**
74 | * Alias for when with suspending function
75 | *
76 | * Warning: Only one method call can be stubbed in the function.
77 | * Subsequent method calls are ignored!
78 | */
79 | fun Stubber.wheneverBlocking(mock: T, f: suspend T.() -> Unit) {
80 | val m = whenever(mock)
81 | runBlocking { m.f() }
82 | }
83 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/Verification.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | import org.mockito.kotlin.internal.createInstance
29 | import kotlinx.coroutines.runBlocking
30 | import org.mockito.Mockito
31 | import org.mockito.kotlin.internal.KInOrderDecorator
32 | import org.mockito.verification.VerificationAfterDelay
33 | import org.mockito.verification.VerificationMode
34 | import org.mockito.verification.VerificationWithTimeout
35 |
36 | /**
37 | * Verifies certain behavior happened once.
38 | *
39 | * Alias for [Mockito.verify].
40 | */
41 | fun verify(mock: T): T {
42 | return Mockito.verify(mock)!!
43 | }
44 |
45 | /**
46 | * Verifies certain suspending behavior happened once.
47 | *
48 | * Warning: Only one method call can be verified in the function.
49 | * Subsequent method calls are ignored!
50 | */
51 | fun verifyBlocking(mock: T, f: suspend T.() -> Unit) {
52 | val m = Mockito.verify(mock)
53 | runBlocking { m.f() }
54 | }
55 |
56 | /**
57 | * Verifies certain behavior happened at least once / exact number of times / never.
58 | *
59 | * Warning: Only one method call can be verified in the function.
60 | * Subsequent method calls are ignored!
61 | */
62 | fun verifyBlocking(mock: T, mode: VerificationMode, f: suspend T.() -> Unit) {
63 | val m = Mockito.verify(mock, mode)
64 | runBlocking { m.f() }
65 | }
66 |
67 | /**
68 | * Verifies certain behavior happened at least once / exact number of times / never.
69 | *
70 | * Alias for [Mockito.verify].
71 | */
72 | fun verify(mock: T, mode: VerificationMode): T {
73 | return Mockito.verify(mock, mode)!!
74 | }
75 |
76 | /**
77 | * Verifies that no interactions happened on given mocks beyond the previously verified interactions.
78 | *
79 | * Alias for [Mockito.verifyNoMoreInteractions].
80 | */
81 | fun verifyNoMoreInteractions(vararg mocks: T) {
82 | Mockito.verifyNoMoreInteractions(*mocks)
83 | }
84 |
85 | /**
86 | * Checks if any of given mocks has any unverified interaction.
87 | *
88 | * Alias for [Mockito.verifyNoInteractions].
89 | */
90 | fun verifyNoInteractions(vararg mocks: Any) {
91 | Mockito.verifyNoInteractions(*mocks)
92 | }
93 |
94 | /**
95 | * Allows verifying exact number of invocations.
96 | *
97 | * Alias for [Mockito.times].
98 | */
99 | fun times(numInvocations: Int): VerificationMode {
100 | return Mockito.times(numInvocations)!!
101 | }
102 |
103 | /**
104 | * Allows at-least-x verification.
105 | *
106 | * Alias for [Mockito.atLeast].
107 | */
108 | fun atLeast(numInvocations: Int): VerificationMode {
109 | return Mockito.atLeast(numInvocations)!!
110 | }
111 |
112 | /**
113 | * Allows at-least-once verification.
114 | *
115 | * Alias for [Mockito.atLeastOnce].
116 | */
117 | fun atLeastOnce(): VerificationMode {
118 | return Mockito.atLeastOnce()!!
119 | }
120 |
121 | /**
122 | * Allows at-most-x verification.
123 | *
124 | * Alias for [Mockito.atMost].
125 | */
126 | fun atMost(maxNumberOfInvocations: Int): VerificationMode {
127 | return Mockito.atMost(maxNumberOfInvocations)!!
128 | }
129 |
130 | /**
131 | * Allows non-greedy verification in order.
132 | *
133 | * Alias for [Mockito.calls].
134 | */
135 | fun calls(wantedNumberOfInvocations: Int): VerificationMode {
136 | return Mockito.calls(wantedNumberOfInvocations)!!
137 | }
138 |
139 | /**
140 | * Alias for [times] with parameter `0`.
141 | */
142 | fun never(): VerificationMode {
143 | return Mockito.never()!!
144 | }
145 |
146 | /**
147 | * Use this method in order to only clear invocations, when stubbing is non-trivial.
148 | *
149 | * Alias for [Mockito.clearInvocations].
150 | */
151 | fun clearInvocations(vararg mocks: T) {
152 | Mockito.clearInvocations(*mocks)
153 | }
154 |
155 | /**
156 | * Adds a description to be printed if verification fails.
157 | *
158 | * Alias for [Mockito.description].
159 | */
160 | fun description(description: String): VerificationMode {
161 | return Mockito.description(description)
162 | }
163 |
164 | /**
165 | * Allows verifying over a given period. It causes a verify to wait for a specified period of time for a desired
166 | * interaction rather than failing immediately if has not already happened. May be useful for testing in concurrent
167 | * conditions.
168 | */
169 | fun after(millis: Long): VerificationAfterDelay {
170 | return Mockito.after(millis)!!
171 | }
172 |
173 | /**
174 | * Allows verifying with timeout. It causes a verify to wait for a specified period of time for a desired
175 | * interaction rather than fails immediately if has not already happened. May be useful for testing in concurrent
176 | * conditions.
177 | */
178 | fun timeout(millis: Long): VerificationWithTimeout {
179 | return Mockito.timeout(millis)!!
180 | }
181 |
182 | /**
183 | * Ignores stubbed methods of given mocks for the sake of verification.
184 | *
185 | * Alias for [Mockito.ignoreStubs].
186 | */
187 | fun ignoreStubs(vararg mocks: Any): Array {
188 | return Mockito.ignoreStubs(*mocks)!!
189 | }
190 |
191 | /**
192 | * Creates [KInOrder] object that allows verifying mocks in order.
193 | *
194 | * Wrapper for [Mockito.inOrder] that also allows to verify suspending method calls.
195 | */
196 | fun inOrder(vararg mocks: Any): KInOrder {
197 | return KInOrderDecorator(Mockito.inOrder(*mocks)!!)
198 | }
199 |
200 | /**
201 | * Creates [KInOrder] object that allows verifying mocks in order.
202 | * Accepts a lambda to allow easy evaluation.
203 | *
204 | * Wrapper for [Mockito.inOrder] that also allows to verify suspending method calls.
205 | */
206 | inline fun inOrder(
207 | vararg mocks: Any,
208 | evaluation: KInOrder.() -> Unit
209 | ) {
210 | KInOrderDecorator(Mockito.inOrder(*mocks)).evaluation()
211 | }
212 |
213 | /**
214 | * Allows [KInOrder] verification for a single mocked instance:
215 | *
216 | * mock.inOrder {
217 | * verify().foo()
218 | * verifyBlocking { bar() }
219 | * }
220 | *
221 | */
222 | inline fun T.inOrder(block: InOrderOnType.() -> Any) {
223 | block.invoke(InOrderOnType(this))
224 | }
225 |
226 | class InOrderOnType(private val t: T) : KInOrder by inOrder(t as Any) {
227 |
228 | /**
229 | * Verifies certain behavior happened once in order.
230 | */
231 | fun verify(): T = verify(t)
232 |
233 | /**
234 | * Verifies certain behavior happened at least once / exact number of times / never in order.
235 | */
236 | fun verify(mode: VerificationMode): T = verify(t, mode)
237 |
238 | /**
239 | * Verifies certain suspending behavior happened once in order.
240 | *
241 | * Warning: Only one method call can be verified in the function.
242 | * Subsequent method calls are ignored!
243 | */
244 | fun verifyBlocking(f: suspend T.() -> Unit) = verifyBlocking(t, f)
245 |
246 | /**
247 | * Verifies certain suspending behavior happened at least once / exact number of times / never in order.
248 | *
249 | * Warning: Only one method call can be verified in the function.
250 | * Subsequent method calls are ignored!
251 | */
252 | fun verifyBlocking(mode: VerificationMode, f: suspend T.() -> Unit) = verifyBlocking(t, mode, f)
253 | }
254 |
255 | /**
256 | * Allows checking if given method was the only one invoked.
257 | */
258 | fun only(): VerificationMode {
259 | return Mockito.only()!!
260 | }
261 |
262 | /**
263 | * For usage with verification only.
264 | *
265 | * For example:
266 | * verify(myObject).doSomething(check { assertThat(it, is("Test")) })
267 | *
268 | * @param predicate A function that performs actions to verify an argument [T].
269 | */
270 | inline fun check(noinline predicate: (T) -> Unit): T {
271 | return Mockito.argThat { arg: T? ->
272 | if (arg == null) error(
273 | """
274 | The argument passed to the predicate was null.
275 |
276 | If you are trying to verify an argument to be null, use `isNull()`.
277 | If you are using `check` as part of a stubbing, use `argThat` or `argForWhich` instead.
278 | """.trimIndent()
279 | )
280 |
281 | try {
282 | predicate(arg)
283 | true
284 | } catch (e: Error) {
285 | e.printStackTrace()
286 | false
287 | }
288 | } ?: createInstance(T::class)
289 | }
290 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/VerifyScope.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin
27 |
28 | /**
29 | * Verify multiple calls on mock
30 | * Supports an easier to read style of
31 | *
32 | * ```
33 | * verify(mock) {
34 | * 2 * { call() }
35 | * }
36 | * ```
37 | */
38 | inline fun verify(mock: T, block: VerifyScope.() -> Unit) {
39 | VerifyScope(mock).block()
40 | }
41 |
42 | class VerifyScope(val mock: T) {
43 |
44 | operator inline fun Int.times(call: T.() -> Unit) {
45 | verify(mock, org.mockito.kotlin.times(this)).call()
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/internal/CreateInstance.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin.internal
27 |
28 | import kotlin.reflect.KClass
29 |
30 | inline fun createInstance(): T {
31 | return when (T::class) {
32 | Boolean::class -> false as T
33 | Byte::class -> 0.toByte() as T
34 | Char::class -> 0.toChar() as T
35 | Short::class -> 0.toShort() as T
36 | Int::class -> 0 as T
37 | Long::class -> 0L as T
38 | Float::class -> 0f as T
39 | Double::class -> 0.0 as T
40 | else -> createInstance(T::class)
41 | }
42 | }
43 |
44 | fun createInstance(@Suppress("UNUSED_PARAMETER") kClass: KClass): T {
45 | return castNull()
46 | }
47 |
48 | /**
49 | * Uses a quirk in the bytecode generated by Kotlin
50 | * to cast [null] to a non-null type.
51 | *
52 | * See https://youtrack.jetbrains.com/issue/KT-8135.
53 | */
54 | @Suppress("UNCHECKED_CAST")
55 | private fun castNull(): T = null as T
56 |
--------------------------------------------------------------------------------
/mockito-kotlin/src/main/kotlin/org/mockito/kotlin/internal/KAnswer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2018 Niek Haarman
5 | * Copyright (c) 2007 Mockito contributors
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | */
25 |
26 | package org.mockito.kotlin.internal
27 |
28 | import org.mockito.invocation.InvocationOnMock
29 | import org.mockito.kotlin.KInvocationOnMock
30 | import org.mockito.stubbing.Answer
31 |
32 | /**
33 | * This class wraps destructuring lambda into [Answer]
34 | */
35 | @Suppress("UNCHECKED_CAST")
36 | internal class KAnswer(
37 | private val body: (KInvocationOnMock) -> T?
38 | ) : Answer