diff --git a/README.md b/README.md index f3ae7b78..b72c93ef 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,9 @@ The library has independent developers, release cycle and versioning from core m ## Dependency -* Artifact identifier: "org.mockito:mockito-scala_:" -* Artifact identifier: "org.mockito:mockito-scala-scalatest_:" -* Artifact identifier: "org.mockito:mockito-scala-specs2_:" +* Artifact identifier: "org.mockito:mockito-scala_[scala-version]:[version]" +* Artifact identifier: "org.mockito:mockito-scala-scalatest_[scala-version]:[version]" +* Artifact identifier: "org.mockito:mockito-scala-specs2_[scala-version]:[version]" * Latest version - see [release notes](/docs/release-notes.md) * Repositories: [Maven Central](https://search.maven.org/search?q=mockito-scala) or [JFrog's Bintray](https://bintray.com/mockito/maven/mockito-scala) diff --git a/common/src/main/scala/org/mockito/internal/stubbing/answers/ScalaThrowsException.scala b/common/src/main/scala/org/mockito/internal/stubbing/answers/ScalaThrowsException.scala new file mode 100644 index 00000000..8a51a16e --- /dev/null +++ b/common/src/main/scala/org/mockito/internal/stubbing/answers/ScalaThrowsException.scala @@ -0,0 +1,7 @@ +package org.mockito.internal.stubbing.answers +import org.mockito.internal.exceptions.Reporter.cannotStubWithNullThrowable +import org.mockito.invocation.InvocationOnMock + +class ScalaThrowsException(t: Throwable) extends ThrowsException(t) { + override def validateFor(invocation: InvocationOnMock): Unit = if (t == null) throw cannotStubWithNullThrowable +} diff --git a/common/src/main/scala/org/mockito/stubbing/ScalaBaseStubbing.scala b/common/src/main/scala/org/mockito/stubbing/ScalaBaseStubbing.scala new file mode 100644 index 00000000..f4b5f3a2 --- /dev/null +++ b/common/src/main/scala/org/mockito/stubbing/ScalaBaseStubbing.scala @@ -0,0 +1,78 @@ +package org.mockito.stubbing + +import org.mockito.internal.ValueClassExtractor +import org.mockito.internal.stubbing.answers.ScalaThrowsException +import org.mockito.invocation.InvocationOnMock +import org.mockito.{ clazz, functionToAnswer, invocationToAnswer } +import org.objenesis.ObjenesisStd + +import scala.language.implicitConversions +import scala.reflect.ClassTag + +trait ScalaBaseStubbing[T] { + + protected def delegate: OngoingStubbing[T] + protected implicit def $vce: ValueClassExtractor[T] + + protected def _thenReturn(value: T, values: Seq[T]): ScalaOngoingStubbing[T] = + delegate.thenReturn($vce.extractAs[T](value), values.map($vce.extractAs[T]): _*) + + private def thenThrow(t: Throwable): ScalaOngoingStubbing[T] = delegate thenAnswer new ScalaThrowsException(t) + + protected def _thenThrow(throwables: Seq[Throwable]): ScalaOngoingStubbing[T] = + if (throwables == null || throwables.isEmpty) thenThrow(null) + else + throwables.tail.foldLeft(thenThrow(throwables.head)) { + case (os, t) => os andThenThrow t + } + + protected def _thenThrow[E <: Throwable: ClassTag]: ScalaOngoingStubbing[T] = thenThrow((new ObjenesisStd).newInstance(clazz)) + + protected def _thenCallRealMethod(): ScalaOngoingStubbing[T] = delegate.thenCallRealMethod() + + protected def _thenAnswer(f: => T): ScalaOngoingStubbing[T] = delegate thenAnswer invocationToAnswer(_ => f) + protected def _thenAnswer[P0: ClassTag](f: P0 => T): ScalaOngoingStubbing[T] = clazz[P0] match { + case c if c == classOf[InvocationOnMock] => delegate thenAnswer invocationToAnswer(i => f(i.asInstanceOf[P0])) + case _ => delegate thenAnswer functionToAnswer(f) + } + protected def _thenAnswer[P0, P1](f: (P0, P1) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2](f: (P0, P1, P2) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3](f: (P0, P1, P2, P3) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3, P4](f: (P0, P1, P2, P3, P4) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3, P4, P5](f: (P0, P1, P2, P3, P4, P5) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3, P4, P5, P6](f: (P0, P1, P2, P3, P4, P5, P6) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7](f: (P0, P1, P2, P3, P4, P5, P6, P7) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8](f: (P0, P1, P2, P3, P4, P5, P6, P7, P8) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8, P9]( + f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + protected def _thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10]( + f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => T): ScalaOngoingStubbing[T] = + delegate thenAnswer functionToAnswer(f) + + /** + * Returns the mock that was used for this stub. + *

+ * It allows to create a stub in one line of code. + * This can be helpful to keep test code clean. + * For example, some boring stub can be created & stubbed at field initialization in a test: + *


+   * public class CarTest {
+   *   Car boringStubbedCar = when(mock(Car.class).shiftGear()).thenThrow(EngineNotStarted.class).getMock();
+   *
+   *   @Test public void should... {}
+   * 
+ * + * @param The mock type given by the variable type. + * @return Mock used in this ongoing stubbing. + */ + def getMock[M]: M = delegate.getMock[M] +} diff --git a/common/src/main/scala/org/mockito/stubbing/ScalaFirstStubbing.scala b/common/src/main/scala/org/mockito/stubbing/ScalaFirstStubbing.scala index f42c492e..c21d434f 100644 --- a/common/src/main/scala/org/mockito/stubbing/ScalaFirstStubbing.scala +++ b/common/src/main/scala/org/mockito/stubbing/ScalaFirstStubbing.scala @@ -5,7 +5,6 @@ import org.mockito.internal.stubbing.OngoingStubbingImpl import org.mockito.internal.util.MockUtil.getMockSettings import org.mockito.invocation.InvocationOnMock import org.mockito.quality.Strictness.LENIENT -import org.mockito.{ clazz, functionToAnswer, invocationToAnswer } import scala.language.implicitConversions import scala.reflect.ClassTag @@ -15,7 +14,8 @@ object ScalaFirstStubbing { implicit def toMock[T](s: ScalaFirstStubbing[_]): T = s.getMock[T] } -case class ScalaFirstStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: ValueClassExtractor[T]) { +case class ScalaFirstStubbing[T](delegate: OngoingStubbing[T])(implicit protected val $vce: ValueClassExtractor[T]) + extends ScalaBaseStubbing[T] { //noinspection AccessorLikeMethodIsUnit def isLenient(): Unit = { @@ -42,8 +42,7 @@ case class ScalaFirstStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: Va * @param values next return values * @return object that allows stubbing consecutive calls */ - def thenReturn(value: T, values: T*): ScalaOngoingStubbing[T] = - delegate.thenReturn($vce.extractAs[T](value), values.map($vce.extractAs[T]): _*) + def thenReturn(value: T, values: T*): ScalaOngoingStubbing[T] = _thenReturn(value, values) /** * Sets one or more Throwable objects to be thrown when the method is called. E.g: @@ -65,7 +64,7 @@ case class ScalaFirstStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: Va * @param throwables to be thrown on method invocation * @return object that allows stubbing consecutive calls */ - def thenThrow(throwables: Throwable*): ScalaOngoingStubbing[T] = delegate thenThrow (throwables: _*) + def thenThrow(throwables: Throwable*): ScalaOngoingStubbing[T] = _thenThrow(throwables) /** * Sets a Throwable type to be thrown when the method is called. E.g: @@ -88,7 +87,7 @@ case class ScalaFirstStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: Va * @param throwableType to be thrown on method invocation * @return object that allows stubbing consecutive calls */ - def thenThrow[E <: Throwable: ClassTag]: ScalaOngoingStubbing[T] = delegate thenThrow clazz + def thenThrow[E <: Throwable: ClassTag]: ScalaOngoingStubbing[T] = _thenThrow /** * Sets the real implementation to be called when the method is called on a mock object. @@ -119,50 +118,20 @@ case class ScalaFirstStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: Va * * @return object that allows stubbing consecutive calls */ - def thenCallRealMethod(): ScalaOngoingStubbing[T] = delegate.thenCallRealMethod() + def thenCallRealMethod(): ScalaOngoingStubbing[T] = _thenCallRealMethod() - def thenAnswer(f: => T): ScalaOngoingStubbing[T] = delegate thenAnswer invocationToAnswer(_ => f) - def thenAnswer[P0: ClassTag](f: P0 => T): ScalaOngoingStubbing[T] = clazz[P0] match { - case c if c == classOf[InvocationOnMock] => delegate thenAnswer invocationToAnswer(i => f(i.asInstanceOf[P0])) - case _ => delegate thenAnswer functionToAnswer(f) - } - def thenAnswer[P0, P1](f: (P0, P1) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def thenAnswer[P0, P1, P2](f: (P0, P1, P2) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def thenAnswer[P0, P1, P2, P3](f: (P0, P1, P2, P3) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def thenAnswer[P0, P1, P2, P3, P4](f: (P0, P1, P2, P3, P4) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def thenAnswer[P0, P1, P2, P3, P4, P5](f: (P0, P1, P2, P3, P4, P5) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def thenAnswer[P0, P1, P2, P3, P4, P5, P6](f: (P0, P1, P2, P3, P4, P5, P6) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7](f: (P0, P1, P2, P3, P4, P5, P6, P7) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8](f: (P0, P1, P2, P3, P4, P5, P6, P7, P8) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) + def thenAnswer(f: => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0: ClassTag](f: P0 => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1](f: (P0, P1) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1, P2](f: (P0, P1, P2) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1, P2, P3](f: (P0, P1, P2, P3) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1, P2, P3, P4](f: (P0, P1, P2, P3, P4) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1, P2, P3, P4, P5](f: (P0, P1, P2, P3, P4, P5) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1, P2, P3, P4, P5, P6](f: (P0, P1, P2, P3, P4, P5, P6) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7](f: (P0, P1, P2, P3, P4, P5, P6, P7) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8](f: (P0, P1, P2, P3, P4, P5, P6, P7, P8) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) def thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8, P9](f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) + _thenAnswer(f) def thenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10]( - f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - - /** - * Returns the mock that was used for this stub. - *

- * It allows to create a stub in one line of code. - * This can be helpful to keep test code clean. - * For example, some boring stub can be created & stubbed at field initialization in a test: - *


-   * public class CarTest {
-   *   Car boringStubbedCar = when(mock(Car.class).shiftGear()).thenThrow(EngineNotStarted.class).getMock();
-   *
-   *   @Test public void should... {}
-   * 
- * - * @param The mock type given by the variable type. - * @return Mock used in this ongoing stubbing. - */ - def getMock[M]: M = delegate.getMock[M] + f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) } diff --git a/common/src/main/scala/org/mockito/stubbing/ScalaOngoingStubbing.scala b/common/src/main/scala/org/mockito/stubbing/ScalaOngoingStubbing.scala index 740e4dbf..755e0f3c 100644 --- a/common/src/main/scala/org/mockito/stubbing/ScalaOngoingStubbing.scala +++ b/common/src/main/scala/org/mockito/stubbing/ScalaOngoingStubbing.scala @@ -1,8 +1,6 @@ package org.mockito.stubbing -import org.mockito._ import org.mockito.internal.ValueClassExtractor -import org.mockito.invocation.InvocationOnMock import scala.language.implicitConversions import scala.reflect.ClassTag @@ -12,7 +10,8 @@ object ScalaOngoingStubbing { implicit def toMock[T](s: ScalaOngoingStubbing[_]): T = s.getMock[T] } -case class ScalaOngoingStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: ValueClassExtractor[T]) { +case class ScalaOngoingStubbing[T](delegate: OngoingStubbing[T])(implicit protected val $vce: ValueClassExtractor[T]) + extends ScalaBaseStubbing[T] { /** * Sets consecutive return values to be returned when the method is called. E.g: @@ -28,8 +27,7 @@ case class ScalaOngoingStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: * @param values next return values * @return object that allows stubbing consecutive calls */ - def andThen(value: T, values: T*): ScalaOngoingStubbing[T] = - delegate.thenReturn($vce.extractAs[T](value), values.map($vce.extractAs[T]): _*) + def andThen(value: T, values: T*): ScalaOngoingStubbing[T] = _thenReturn(value, values) /** * Sets Throwable objects to be thrown when the method is called. E.g: @@ -50,7 +48,7 @@ case class ScalaOngoingStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: * @param throwables to be thrown on method invocation * @return object that allows stubbing consecutive calls */ - def andThenThrow(throwables: Throwable*): ScalaOngoingStubbing[T] = delegate thenThrow (throwables: _*) + def andThenThrow(throwables: Throwable*): ScalaOngoingStubbing[T] = _thenThrow(throwables) /** * Sets a Throwable type to be thrown when the method is called. E.g: @@ -73,7 +71,7 @@ case class ScalaOngoingStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: * @param throwableType to be thrown on method invocation * @return object that allows stubbing consecutive calls */ - def andThenThrow[E <: Throwable: ClassTag]: ScalaOngoingStubbing[T] = delegate thenThrow clazz + def andThenThrow[E <: Throwable: ClassTag]: ScalaOngoingStubbing[T] = _thenThrow /** * Sets the real implementation to be called when the method is called on a mock object. @@ -104,63 +102,21 @@ case class ScalaOngoingStubbing[T](delegate: OngoingStubbing[T])(implicit $vce: * * @return object that allows stubbing consecutive calls */ - def andThenCallRealMethod(): ScalaOngoingStubbing[T] = delegate.thenCallRealMethod() + def andThenCallRealMethod(): ScalaOngoingStubbing[T] = _thenCallRealMethod() - /** - * Sets a generic Answer for the method. E.g: - *

-   * when(mock.someMethod(10)).thenAnswer(new Answer<Integer>() {
-   *     public Integer answer(InvocationOnMock invocation) throws Throwable {
-   *         return (Integer) invocation.getArguments()[0];
-   *     }
-   * }
-   * 
- * - * @param answer the custom answer to execute. - * @return object that allows stubbing consecutive calls - */ - def andThenAnswer(f: => T): ScalaOngoingStubbing[T] = delegate thenAnswer invocationToAnswer(_ => f) - def andThenAnswer[P0: ClassTag](f: P0 => T): ScalaOngoingStubbing[T] = clazz[P0] match { - case c if c == classOf[InvocationOnMock] => delegate thenAnswer invocationToAnswer(i => f(i.asInstanceOf[P0])) - case _ => delegate thenAnswer functionToAnswer(f) - } - def andThenAnswer[P0, P1](f: (P0, P1) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def andThenAnswer[P0, P1, P2](f: (P0, P1, P2) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def andThenAnswer[P0, P1, P2, P3](f: (P0, P1, P2, P3) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def andThenAnswer[P0, P1, P2, P3, P4](f: (P0, P1, P2, P3, P4) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def andThenAnswer[P0, P1, P2, P3, P4, P5](f: (P0, P1, P2, P3, P4, P5) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def andThenAnswer[P0, P1, P2, P3, P4, P5, P6](f: (P0, P1, P2, P3, P4, P5, P6) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - def andThenAnswer[P0, P1, P2, P3, P4, P5, P6, P7](f: (P0, P1, P2, P3, P4, P5, P6, P7) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) + def andThenAnswer(f: => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0: ClassTag](f: P0 => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0, P1](f: (P0, P1) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0, P1, P2](f: (P0, P1, P2) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0, P1, P2, P3](f: (P0, P1, P2, P3) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0, P1, P2, P3, P4](f: (P0, P1, P2, P3, P4) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0, P1, P2, P3, P4, P5](f: (P0, P1, P2, P3, P4, P5) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0, P1, P2, P3, P4, P5, P6](f: (P0, P1, P2, P3, P4, P5, P6) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) + def andThenAnswer[P0, P1, P2, P3, P4, P5, P6, P7](f: (P0, P1, P2, P3, P4, P5, P6, P7) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) def andThenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8](f: (P0, P1, P2, P3, P4, P5, P6, P7, P8) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) + _thenAnswer(f) def andThenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8, P9](f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) + _thenAnswer(f) def andThenAnswer[P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10]( - f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => T): ScalaOngoingStubbing[T] = - delegate thenAnswer functionToAnswer(f) - - /** - * Returns the mock that was used for this stub. - *

- * It allows to create a stub in one line of code. - * This can be helpful to keep test code clean. - * For example, some boring stub can be created & stubbed at field initialization in a test: - *


-   * public class CarTest {
-   *   Car boringStubbedCar = when(mock(Car.class).shiftGear()).thenThrow(EngineNotStarted.class).getMock();
-   *
-   *   @Test public void should... {}
-   * 
- * - * @param The mock type given by the variable type. - * @return Mock used in this ongoing stubbing. - */ - def getMock[M]: M = delegate.getMock[M] + f: (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) => T): ScalaOngoingStubbing[T] = _thenAnswer(f) } diff --git a/scalatest/src/test/scala/user/org/mockito/MockitoSugarTest.scala b/scalatest/src/test/scala/user/org/mockito/MockitoSugarTest.scala index 20496e1c..f1ff3b12 100644 --- a/scalatest/src/test/scala/user/org/mockito/MockitoSugarTest.scala +++ b/scalatest/src/test/scala/user/org/mockito/MockitoSugarTest.scala @@ -117,6 +117,36 @@ class MockitoSugarTest aMock.returnBar shouldBe a[Bar] } + "stub a runtime exception instance to be thrown" in { + val aMock = foo() + + when(aMock.bar) thenThrow new IllegalArgumentException + + an[IllegalArgumentException] shouldBe thrownBy(aMock.bar) + } + + "stub a checked exception instance to be thrown" in { + val aMock = foo() + + when(aMock.bar) thenThrow new Exception + + an[Exception] shouldBe thrownBy(aMock.bar) + } + + "stub a multiple exceptions instance to be thrown" in { + val aMock = foo() + + when(aMock.bar) thenThrow new Exception andThenThrow new IllegalArgumentException + + an[Exception] shouldBe thrownBy(aMock.bar) + an[IllegalArgumentException] shouldBe thrownBy(aMock.bar) + + when(aMock.returnBar) thenThrow new IllegalArgumentException andThenThrow new Exception + + an[IllegalArgumentException] shouldBe thrownBy(aMock.returnBar) + an[Exception] shouldBe thrownBy(aMock.returnBar) + } + "default answer should deal with default arguments" in { val aMock = foo()