Skip to content

Commit 35f728d

Browse files
authored
Merge pull request #266 from nhaarman/constructor-parameters
Support mocking with constructor arguments
2 parents 879a926 + efe2ab1 commit 35f728d

File tree

3 files changed

+56
-11
lines changed

3 files changed

+56
-11
lines changed

mockito-kotlin/src/main/kotlin/com/nhaarman/mockitokotlin2/Mocking.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ inline fun <reified T : Any> mock(
5959
verboseLogging: Boolean = false,
6060
invocationListeners: Array<InvocationListener>? = null,
6161
stubOnly: Boolean = false,
62-
@Incubating useConstructor: Boolean = false,
62+
@Incubating useConstructor: UseConstructor? = null,
6363
@Incubating outerInstance: Any? = null
6464
): T {
6565
return Mockito.mock(
@@ -105,7 +105,7 @@ inline fun <reified T : Any> mock(
105105
verboseLogging: Boolean = false,
106106
invocationListeners: Array<InvocationListener>? = null,
107107
stubOnly: Boolean = false,
108-
@Incubating useConstructor: Boolean = false,
108+
@Incubating useConstructor: UseConstructor? = null,
109109
@Incubating outerInstance: Any? = null,
110110
stubbing: KStubbing<T>.(T) -> Unit
111111
): T {
@@ -153,7 +153,7 @@ fun withSettings(
153153
verboseLogging: Boolean = false,
154154
invocationListeners: Array<InvocationListener>? = null,
155155
stubOnly: Boolean = false,
156-
@Incubating useConstructor: Boolean = false,
156+
@Incubating useConstructor: UseConstructor? = null,
157157
@Incubating outerInstance: Any? = null
158158
): MockSettings = Mockito.withSettings().apply {
159159
extraInterfaces?.let { extraInterfaces(*it.map { it.java }.toTypedArray()) }
@@ -165,10 +165,23 @@ fun withSettings(
165165
if (verboseLogging) verboseLogging()
166166
invocationListeners?.let { invocationListeners(*it) }
167167
if (stubOnly) stubOnly()
168-
if (useConstructor) useConstructor()
168+
useConstructor?.let { useConstructor(*it.args) }
169169
outerInstance?.let { outerInstance(it) }
170170
}
171171

172+
class UseConstructor private constructor(val args: Array<Any>) {
173+
174+
companion object {
175+
176+
/** Invokes the parameterless constructor. */
177+
fun parameterless() = UseConstructor(emptyArray())
178+
179+
/** Invokes a constructor with given arguments. */
180+
fun withArguments(vararg arguments: Any): UseConstructor {
181+
return UseConstructor(arguments.asList().toTypedArray())
182+
}
183+
}
184+
}
172185

173186
@Deprecated(
174187
"Use mock() with optional arguments instead.",

tests/src/test/kotlin/test/Classes.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ abstract class ThrowingConstructor {
7575
}
7676
}
7777

78+
abstract class ThrowingConstructorWithArgument {
79+
80+
constructor(s: String) {
81+
error("Error in constructor: $s")
82+
}
83+
}
84+
85+
abstract class NonThrowingConstructorWithArgument {
86+
87+
constructor() {
88+
error("Error in constructor")
89+
}
90+
91+
constructor(s: String)
92+
}
93+
7894
interface GenericMethods<T> {
7995
fun genericMethod(): T
8096
fun nullableReturnType(): T?

tests/src/test/kotlin/test/MockingTest.kt

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package test
33
import com.nhaarman.expect.expect
44
import com.nhaarman.expect.expectErrorWithMessage
55
import com.nhaarman.expect.fail
6-
import com.nhaarman.mockitokotlin2.doReturn
7-
import com.nhaarman.mockitokotlin2.mock
8-
import com.nhaarman.mockitokotlin2.verify
9-
import com.nhaarman.mockitokotlin2.whenever
6+
import com.nhaarman.mockitokotlin2.*
7+
import com.nhaarman.mockitokotlin2.UseConstructor.Companion
8+
import com.nhaarman.mockitokotlin2.UseConstructor.Companion.parameterless
9+
import com.nhaarman.mockitokotlin2.UseConstructor.Companion.withArguments
1010
import org.junit.Test
1111
import org.mockito.Mockito
1212
import org.mockito.exceptions.verification.WantedButNotInvoked
@@ -103,7 +103,6 @@ class MockingTest : TestBase() {
103103
}
104104

105105

106-
107106
@Test
108107
fun mock_withCustomDefaultAnswer_parameterName() {
109108
/* Given */
@@ -215,10 +214,27 @@ class MockingTest : TestBase() {
215214
fun mock_withSettingsAPI_useConstructor() {
216215
/* Given */
217216
expectErrorWithMessage("Unable to create mock instance of type ") on {
218-
mock<ThrowingConstructor>(useConstructor = true) {}
217+
mock<ThrowingConstructor>(useConstructor = parameterless()) {}
218+
}
219+
}
220+
221+
@Test
222+
fun mock_withSettingsAPI_useConstructorWithArguments_failing() {
223+
/* Given */
224+
expectErrorWithMessage("Unable to create mock instance of type ") on {
225+
mock<ThrowingConstructorWithArgument>(useConstructor = withArguments("Test")) {}
219226
}
220227
}
221228

229+
@Test
230+
fun mock_withSettingsAPI_useConstructorWithArguments() {
231+
/* When */
232+
val result = mock<NonThrowingConstructorWithArgument>(useConstructor = withArguments("Test")) {}
233+
234+
/* Then */
235+
expect(result).toNotBeNull()
236+
}
237+
222238
@Test
223239
fun mockStubbing_withSettingsAPI_extraInterfaces() {
224240
/* Given */
@@ -316,7 +332,7 @@ class MockingTest : TestBase() {
316332
fun mockStubbing_withSettingsAPI_useConstructor() {
317333
/* Given */
318334
expectErrorWithMessage("Unable to create mock instance of type ") on {
319-
mock<ThrowingConstructor>(useConstructor = true) {}
335+
mock<ThrowingConstructor>(useConstructor = parameterless()) {}
320336
}
321337
}
322338

0 commit comments

Comments
 (0)