From 5204cea657bd138990398f36964beb1391b264cd Mon Sep 17 00:00:00 2001 From: Bruno Bonanno <241804+bbonanno@users.noreply.github.com> Date: Tue, 14 May 2019 10:54:31 +0100 Subject: [PATCH 1/3] Fix trait hierarchy --- cats/src/main/scala/org/mockito/cats/CatsStubbing.scala | 2 +- .../scala/org/mockito/cats/IdiomaticMockitoCats.scala | 2 +- cats/src/main/scala/org/mockito/cats/MockitoCats.scala | 2 +- common/src/main/scala/org/mockito/MockitoAPI.scala | 8 +++++--- .../src/main/scala/org/mockito/IdiomaticMockitoBase.scala | 2 +- core/src/main/scala/org/mockito/MockitoSugar.scala | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cats/src/main/scala/org/mockito/cats/CatsStubbing.scala b/cats/src/main/scala/org/mockito/cats/CatsStubbing.scala index a3a1463f..2f19ee15 100644 --- a/cats/src/main/scala/org/mockito/cats/CatsStubbing.scala +++ b/cats/src/main/scala/org/mockito/cats/CatsStubbing.scala @@ -1,7 +1,7 @@ package org.mockito.cats import cats.implicits._ -import cats.{Applicative, ApplicativeError} +import cats.{ Applicative, ApplicativeError } import org.mockito.stubbing.OngoingStubbing case class CatsStubbing[F[_], T](delegate: OngoingStubbing[F[T]]) { diff --git a/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala b/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala index 356b3ac1..e38a89c1 100644 --- a/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala +++ b/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala @@ -7,7 +7,7 @@ import org.scalactic.Equality import scala.reflect.ClassTag -trait IdiomaticMockitoCats extends IdiomaticMockito { +trait IdiomaticMockitoCats extends ScalacticSerialisableHack { implicit class StubbingOps[F[_], T](stubbing: F[T]) { diff --git a/cats/src/main/scala/org/mockito/cats/MockitoCats.scala b/cats/src/main/scala/org/mockito/cats/MockitoCats.scala index f9ebacb2..d44a1a5b 100644 --- a/cats/src/main/scala/org/mockito/cats/MockitoCats.scala +++ b/cats/src/main/scala/org/mockito/cats/MockitoCats.scala @@ -6,7 +6,7 @@ import org.scalactic.Equality import scala.reflect.ClassTag -trait MockitoCats extends MockitoSugar { +trait MockitoCats extends ScalacticSerialisableHack { def whenF[F[_], T](methodCall: F[T]): CatsStubbing[F, T] = Mockito.when(methodCall) diff --git a/common/src/main/scala/org/mockito/MockitoAPI.scala b/common/src/main/scala/org/mockito/MockitoAPI.scala index f73c44a4..a89129c5 100644 --- a/common/src/main/scala/org/mockito/MockitoAPI.scala +++ b/common/src/main/scala/org/mockito/MockitoAPI.scala @@ -30,6 +30,11 @@ import scala.collection.JavaConverters._ import scala.reflect.ClassTag import scala.reflect.runtime.universe.WeakTypeTag +private[mockito] trait ScalacticSerialisableHack { + //Hack until Equality can be made serialisable + implicit def mockitoSerialisableEquality[T]: Equality[T] = serialisableEquality[T] +} + private[mockito] trait MockCreator { def mock[T <: AnyRef: ClassTag: WeakTypeTag](implicit defaultAnswer: DefaultAnswer, $pt: Prettifier): T def mock[T <: AnyRef: ClassTag: WeakTypeTag](defaultAnswer: Answer[_])(implicit $pt: Prettifier): T = @@ -46,9 +51,6 @@ private[mockito] trait MockCreator { */ def withSettings(implicit defaultAnswer: DefaultAnswer): MockSettings = Mockito.withSettings().defaultAnswer(defaultAnswer) - - //Hack until Equality can be made serialisable - implicit def mockitoSerialisableEquality[T]: Equality[T] = serialisableEquality[T] } //noinspection MutatorLikeMethodIsParameterless diff --git a/core/src/main/scala/org/mockito/IdiomaticMockitoBase.scala b/core/src/main/scala/org/mockito/IdiomaticMockitoBase.scala index 402a7d66..d2fc5a4d 100644 --- a/core/src/main/scala/org/mockito/IdiomaticMockitoBase.scala +++ b/core/src/main/scala/org/mockito/IdiomaticMockitoBase.scala @@ -74,7 +74,7 @@ object IdiomaticMockitoBase { } } -trait IdiomaticMockitoBase extends MockitoEnhancer { +trait IdiomaticMockitoBase extends MockitoEnhancer with ScalacticSerialisableHack { import org.mockito.IdiomaticMockitoBase._ diff --git a/core/src/main/scala/org/mockito/MockitoSugar.scala b/core/src/main/scala/org/mockito/MockitoSugar.scala index 35adc6b9..48f3ed24 100644 --- a/core/src/main/scala/org/mockito/MockitoSugar.scala +++ b/core/src/main/scala/org/mockito/MockitoSugar.scala @@ -1,6 +1,6 @@ package org.mockito -trait MockitoSugar extends MockitoEnhancer with DoSomething with Verifications with Rest +trait MockitoSugar extends MockitoEnhancer with DoSomething with Verifications with Rest with ScalacticSerialisableHack /** * Simple object to allow the usage of the trait without mixing it in From e6dce2d735c8b39454bb0dce9af16490061dbadf Mon Sep 17 00:00:00 2001 From: Bruno Bonanno <241804+bbonanno@users.noreply.github.com> Date: Tue, 14 May 2019 11:01:19 +0100 Subject: [PATCH 2/3] Fix integration with cats.Eq --- .../main/scala/org/mockito/cats/EqToEquality.scala | 13 ++++++++----- .../org/mockito/cats/IdiomaticMockitoCats.scala | 4 +--- .../main/scala/org/mockito/cats/MockitoCats.scala | 4 +--- .../org/mockito/cats/IdiomaticMockitoCatsTest.scala | 4 ++++ .../scala/org/mockito/cats/MockitoCatsTest.scala | 4 ++++ cats/src/test/scala/org/mockito/cats/package.scala | 2 ++ 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/cats/src/main/scala/org/mockito/cats/EqToEquality.scala b/cats/src/main/scala/org/mockito/cats/EqToEquality.scala index 70a9dc19..8b4911a0 100644 --- a/cats/src/main/scala/org/mockito/cats/EqToEquality.scala +++ b/cats/src/main/scala/org/mockito/cats/EqToEquality.scala @@ -2,11 +2,14 @@ package org.mockito.cats import cats.Eq import cats.implicits._ -import org.mockito._ import org.scalactic.Equality -import scala.reflect.ClassTag - -class EqToEquality[T: ClassTag: Eq] extends Equality[T] { - override def areEqual(a: T, b: Any): Boolean = clazz[T].isInstance(b) && a === b.asInstanceOf[T] +class EqToEquality[T: Eq] extends Equality[T] { + override def areEqual(a: T, b: Any): Boolean = + (a == null && b == null) || ( + a != null && + b != null && + b.getClass == a.getClass && + a === b.asInstanceOf[T] + ) } diff --git a/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala b/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala index e38a89c1..5068b0e2 100644 --- a/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala +++ b/cats/src/main/scala/org/mockito/cats/IdiomaticMockitoCats.scala @@ -5,8 +5,6 @@ import org.mockito._ import org.mockito.cats.IdiomaticMockitoCats.{ ReturnActions, ThrowActions } import org.scalactic.Equality -import scala.reflect.ClassTag - trait IdiomaticMockitoCats extends ScalacticSerialisableHack { implicit class StubbingOps[F[_], T](stubbing: F[T]) { @@ -20,7 +18,7 @@ trait IdiomaticMockitoCats extends ScalacticSerialisableHack { def failsWith: ThrowActions[F, T] = macro WhenMacro.shouldThrow[T] } - implicit def catsEquality[T: ClassTag: Eq]: Equality[T] = new EqToEquality[T] + implicit def catsEquality[T: Eq]: Equality[T] = new EqToEquality[T] } object IdiomaticMockitoCats extends IdiomaticMockitoCats { diff --git a/cats/src/main/scala/org/mockito/cats/MockitoCats.scala b/cats/src/main/scala/org/mockito/cats/MockitoCats.scala index d44a1a5b..e78d999c 100644 --- a/cats/src/main/scala/org/mockito/cats/MockitoCats.scala +++ b/cats/src/main/scala/org/mockito/cats/MockitoCats.scala @@ -4,13 +4,11 @@ import cats.Eq import org.mockito._ import org.scalactic.Equality -import scala.reflect.ClassTag - trait MockitoCats extends ScalacticSerialisableHack { def whenF[F[_], T](methodCall: F[T]): CatsStubbing[F, T] = Mockito.when(methodCall) - implicit def catsEquality[T: ClassTag: Eq]: Equality[T] = new EqToEquality[T] + implicit def catsEquality[T: Eq]: Equality[T] = new EqToEquality[T] } object MockitoCats extends MockitoCats diff --git a/cats/src/test/scala/org/mockito/cats/IdiomaticMockitoCatsTest.scala b/cats/src/test/scala/org/mockito/cats/IdiomaticMockitoCatsTest.scala index 2721486f..5507c7c8 100644 --- a/cats/src/test/scala/org/mockito/cats/IdiomaticMockitoCatsTest.scala +++ b/cats/src/test/scala/org/mockito/cats/IdiomaticMockitoCatsTest.scala @@ -69,8 +69,12 @@ class IdiomaticMockitoCatsTest val aMock = mock[Foo] aMock.returnsOptionT(ValueClass("HoLa")) shouldReturnF ValueClass("Mocked!") + aMock.shouldI(false) shouldReturn "Mocked!" + aMock.shouldI(true) shouldReturn "Mocked again!" aMock.returnsOptionT(ValueClass("HOLA")).value should ===(ValueClass("mocked!")) + aMock.shouldI(false) shouldBe "Mocked!" + aMock.shouldI(true) shouldBe "Mocked again!" } } } diff --git a/cats/src/test/scala/org/mockito/cats/MockitoCatsTest.scala b/cats/src/test/scala/org/mockito/cats/MockitoCatsTest.scala index 38c5b51d..892ae419 100644 --- a/cats/src/test/scala/org/mockito/cats/MockitoCatsTest.scala +++ b/cats/src/test/scala/org/mockito/cats/MockitoCatsTest.scala @@ -69,8 +69,12 @@ class MockitoCatsTest val aMock = mock[Foo] whenF(aMock.returnsOptionT(eqTo(ValueClass("HoLa")))) thenReturn ValueClass("Mocked!") + when(aMock.shouldI(eqTo(false))) thenReturn "Mocked!" + when(aMock.shouldI(eqTo(true))) thenReturn "Mocked again!" aMock.returnsOptionT(ValueClass("HOLA")).value should ===(ValueClass("mocked!")) + aMock.shouldI(false) shouldBe "Mocked!" + aMock.shouldI(true) shouldBe "Mocked again!" } } } diff --git a/cats/src/test/scala/org/mockito/cats/package.scala b/cats/src/test/scala/org/mockito/cats/package.scala index 95bef85f..bf1a9841 100644 --- a/cats/src/test/scala/org/mockito/cats/package.scala +++ b/cats/src/test/scala/org/mockito/cats/package.scala @@ -12,6 +12,8 @@ package object cats { def returnsOptionT[T](v: T): Option[T] def returnsMT[M[_], T](v: T): M[T] + + def shouldI(should: Boolean): String } } From 792e57e5011701f7bbbf158aa17a09c176f8d1dc Mon Sep 17 00:00:00 2001 From: Bruno Bonanno Date: Thu, 16 May 2019 19:08:50 +0100 Subject: [PATCH 3/3] Try to fix flaky tests --- .../org/mockito/specs2/MockitoScalaNewSyntaxSpec.scala | 7 +------ .../test/scala/org/mockito/specs2/MockitoScalaSpec.scala | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/specs2/src/test/scala/org/mockito/specs2/MockitoScalaNewSyntaxSpec.scala b/specs2/src/test/scala/org/mockito/specs2/MockitoScalaNewSyntaxSpec.scala index 0284d1c4..b73093e9 100644 --- a/specs2/src/test/scala/org/mockito/specs2/MockitoScalaNewSyntaxSpec.scala +++ b/specs2/src/test/scala/org/mockito/specs2/MockitoScalaNewSyntaxSpec.scala @@ -24,11 +24,6 @@ import scala.concurrent.duration._ class MockitoScalaNewSyntaxSpec extends Spec with Mockito { def is = s2""" - Mockito is a Java library for mocking. - - The following samples are taken from the main documentation which can be found here: - https://static.javadoc.io/org.mockito/mockito-core/2.25.1/org/mockito/Mockito.html - CREATION ======== @@ -358,7 +353,7 @@ The Mockito trait is reusable in other contexts object list extends list; import list._ scala.concurrent.Future { Thread.sleep(2000); takesSometime.call(10) } - ((takesSometime.call(10) wasCalled (once within 10.millis)).message must contain("Wanted but not invoked")) and + ((takesSometime.call(10) was called).message must contain("Wanted but not invoked")) and (takesSometime.call(10) wasCalled (once within 10.seconds)) } diff --git a/specs2/src/test/scala/org/mockito/specs2/MockitoScalaSpec.scala b/specs2/src/test/scala/org/mockito/specs2/MockitoScalaSpec.scala index a2e95a05..708faeb4 100644 --- a/specs2/src/test/scala/org/mockito/specs2/MockitoScalaSpec.scala +++ b/specs2/src/test/scala/org/mockito/specs2/MockitoScalaSpec.scala @@ -23,11 +23,6 @@ import scala.concurrent.duration._ class MockitoScalaSpec extends Spec with Mockito { def is = s2""" - Mockito is a Java library for mocking. - - The following samples are taken from the main documentation which can be found here: - https://static.javadoc.io/org.mockito/mockito-core/2.25.1/org/mockito/Mockito.html - CREATION ======== @@ -357,7 +352,7 @@ The Mockito trait is reusable in other contexts object list extends list; import list._ scala.concurrent.Future { Thread.sleep(2000); takesSometime.call(10) } - ((takesSometime.call(10) wasCalled (once within 10.millis)).message must contain("Wanted but not invoked")) and + ((takesSometime.call(10) was called).message must contain("Wanted but not invoked")) and (takesSometime.call(10) wasCalled (once within 10.seconds)) }