Skip to content

Commit

Permalink
Merge pull request #955 from daniel-dios/add-throw-many-exceptions
Browse files Browse the repository at this point in the history
Adding throwsMany exception
  • Loading branch information
Raibaz committed Nov 2, 2022
2 parents 2b9b52f + 87219d1 commit d1a4acd
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -1321,6 +1321,7 @@ An Answer can be followed up by one or more additional answers.
|`returnsMany list`|specify that the matched call returns a value from the list, with subsequent calls returning the next element|
|`returnsArgument(n)`|specify that the matched call returns the nth argument of that call|
|`throws ex`|specify that the matched call throws an exception|
|`throwsMany ex`| specify that the matched call throws an exception from the list, with subsequent calls throwing the next exception|
|`answers { code }`|specify that the matched call answers with a code block scoped with `answer scope`|
|`coAnswers { code }`|specify that the matched call answers with a coroutine code block with `answer scope`|
|`answers answerObj`|specify that the matched call answers with an Answer object|
Expand All @@ -1341,6 +1342,7 @@ So this is similar to the `returnsMany` semantics.
|`andThen value`|specify that the matched call returns one specified value|
|`andThenMany list`|specify that the matched call returns a value from the list, with subsequent calls returning the next element|
|`andThenThrows ex`|specify that the matched call throws an exception|
|`andThenThrowsMany ex`|specify that the matched call throws an exception from the list, with subsequent calls throwing the next exception|
|`andThen { code }`|specify that the matched call answers with a code block scoped with `answer scope`|
|`coAndThen { code }`|specify that the matched call answers with a coroutine code block with `answer scope`|
|`andThenAnswer answerObj`|specify that the matched call answers with an Answer object|
Expand Down
2 changes: 2 additions & 0 deletions modules/mockk-dsl/api/mockk-dsl.api
Expand Up @@ -486,6 +486,7 @@ public final class io/mockk/MockKAdditionalAnswerScope {
public final fun andThenMany (Ljava/util/List;)Lio/mockk/MockKAdditionalAnswerScope;
public final fun andThenMany ([Ljava/lang/Object;)Lio/mockk/MockKAdditionalAnswerScope;
public final fun andThenThrows (Ljava/lang/Throwable;)Lio/mockk/MockKAdditionalAnswerScope;
public final fun andThenThrowsMany (Ljava/util/List;)Lio/mockk/MockKAdditionalAnswerScope;
public final fun coAndThen (Lkotlin/jvm/functions/Function3;)Lio/mockk/MockKAdditionalAnswerScope;
}

Expand Down Expand Up @@ -927,6 +928,7 @@ public final class io/mockk/MockKStubScope {
public final fun returnsMany (Ljava/util/List;)Lio/mockk/MockKAdditionalAnswerScope;
public final fun returnsMany ([Ljava/lang/Object;)Lio/mockk/MockKAdditionalAnswerScope;
public final fun throws (Ljava/lang/Throwable;)Lio/mockk/MockKAdditionalAnswerScope;
public final fun throwsMany (Ljava/util/List;)Lio/mockk/MockKAdditionalAnswerScope;
}

public final class io/mockk/MockKUnmockKCompositeScope : io/mockk/MockKUnmockKScope {
Expand Down
6 changes: 6 additions & 0 deletions modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt
Expand Up @@ -2133,6 +2133,9 @@ class MockKStubScope<T, B>(

infix fun throws(ex: Throwable) = answers(ThrowingAnswer(ex))

infix fun throwsMany(exList: List<Throwable>): MockKAdditionalAnswerScope<T, B> =
this answers (ManyAnswersAnswer(exList.map { ThrowingAnswer(it) }))

infix fun answers(answer: MockKAnswerScope<T, B>.(Call) -> T) =
answers(FunctionAnswer { MockKAnswerScope<T, B>(lambda, it).answer(it) })

Expand Down Expand Up @@ -2183,6 +2186,9 @@ class MockKAdditionalAnswerScope<T, B>(

infix fun andThenThrows(ex: Throwable) = andThenAnswer(ThrowingAnswer(ex))

infix fun andThenThrowsMany(exList: List<Throwable>) =
andThenAnswer(ManyAnswersAnswer(exList.map { ThrowingAnswer(it) }))

@Deprecated("Use andThenAnswer instead of andThen.")
infix fun andThen(answer: MockKAnswerScope<T, B>.(Call) -> T) =
andThenAnswer(FunctionAnswer { MockKAnswerScope<T, B>(lambda, it).answer(it) })
Expand Down
Expand Up @@ -123,6 +123,53 @@ class AdditionalAnswerTest {
}
}

@Test
fun andThrowsMany() {
val exceptions = listOf(
IllegalArgumentException("error1"),
NullPointerException("error2"),
NoSuchElementException("error3")
)

every { mock.op(any()) } throwsMany exceptions

assertFailsWith(IllegalArgumentException::class) {
mock.op(2)
}
assertFailsWith(NullPointerException::class) {
mock.op(3)
}
assertFailsWith(NoSuchElementException::class) {
mock.op(3)
}
assertFailsWith(NoSuchElementException::class) {
mock.op(4)
}
}

@Test
fun andThenThrowsMany() {
val exceptions = listOf(
IllegalArgumentException("error1"),
NullPointerException("error2"),
NoSuchElementException("error3")
)
every { mock.op(any()) } returns 3 andThenThrowsMany exceptions andThen 2

assertEquals(3, mock.op(1))
assertFailsWith(IllegalArgumentException::class) {
mock.op(2)
}
assertFailsWith(NullPointerException::class) {
mock.op(3)
}
assertFailsWith(NoSuchElementException::class) {
mock.op(3)
}
assertEquals(2, mock.op(4))
assertEquals(2, mock.op(5))
}

@Test
fun arbitraryLengthCheck() {
every {
Expand Down

0 comments on commit d1a4acd

Please sign in to comment.