We need to use mock-maker-inline to mock final classes of some third party library (e.g. Azure SDK).
We are using below versions of scalatest and mockito:
scalaVersion := "2.12.2"
val ScalaTestVersion = "3.2.5"
val ScalaCheckVersion = "1.14.2"
val MockitoVersion = "3.4.0"
val DockerItVersion = "0.9.9"
val MockJavaMailVersion = "1.9"
val MockitoScalaVersion = "1.1.4"
val ScalaPlusScalaCheckVersion = "3.2.2.0"
val ScalaPlusMockitoVersion = "3.2.10.0"
lazy val MockitoIssueSample = (project in file("."))
.settings(
name := "MockitoIssueSample",
libraryDependencies += "org.scalatest" %% "scalatest" % ScalaTestVersion % Test,
libraryDependencies += "org.scalacheck" %% "scalacheck" % ScalaCheckVersion % Test,
libraryDependencies += "org.mockito" % "mockito-core" % MockitoVersion % Test,
libraryDependencies += "org.mockito" %% "mockito-scala" % MockitoScalaVersion % Test,
libraryDependencies += "org.scalatestplus" %% "scalacheck-1-14" % ScalaPlusScalaCheckVersion % Test,
libraryDependencies += "org.scalatestplus" %% "mockito-3-4" % ScalaPlusMockitoVersion % Test,
)
After enabling mock-maker-inline in our Scala application, other test cases which are using trait having final methods are started to fail with below error:
[info] - should should invoke area of the appropriate shape *** FAILED ***
[info] org.mockito.exceptions.misusing.UnnecessaryStubbingException: Unnecessary stubbings detected.
[info] Clean & maintainable test code requires zero unnecessary code.
[info] Following stubbings are unnecessary (click to navigate to relevant line of code):
[info] 1. -> at cortex.mockito.sample.AreaCalculatorSpec$$anon$1.<init>(AreaCalculatorSpec.scala:27)
[info] Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.
[info] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[info] at scala.Option.fold(Option.scala:158)
[info] at cortex.mockito.sample.AreaCalculatorSpec.withFixture(AreaCalculatorSpec.scala:13)
[info] at org.scalatest.wordspec.AnyWordSpecLike.invokeWithFixture$1(AnyWordSpecLike.scala:1075)
[info] at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTest$1(AnyWordSpecLike.scala:1087)
[info] at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
[info] at org.scalatest.wordspec.AnyWordSpecLike.runTest(AnyWordSpecLike.scala:1087)
[info] at org.scalatest.wordspec.AnyWordSpecLike.runTest$(AnyWordSpecLike.scala:1069)
[info] at org.scalatest.wordspec.AnyWordSpec.runTest(AnyWordSpec.scala:1879)
[info] at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTests$1(AnyWordSpecLike.scala:1146)
[info] ...
We have simulated this issue with test Scala application. If we disable mock-maker-inline then this test case works. Here, in this sample application we have added just single problematic test case.
Below is sample code:
Shape.scala
package mockito.sample
trait Shape {
final def printArea(): Unit = {
println(s"Area is: $getArea()")
}
def getArea(): Double
}
Rectangle.scala
package mockito.sample
class Rectangle(l: Long, b: Long) extends Shape {
override def getArea(): Double = {
l * b
}
}
AreaCalculator.scala
package mockito.sample
class AreaCalculator(shape: Shape) {
def printArea(): Boolean = {
shape.printArea()
true
}
}
AreaCalculatorSpec.scala
package mockito.sample
import org.mockito.integrations.scalatest.IdiomaticMockitoFixture
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.matchers.must.Matchers.convertToAnyMustWrapper
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.{EitherValues, TryValues}
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
class AreaCalculatorSpec extends AnyWordSpec
with Matchers
with ScalaFutures
with EitherValues
with TryValues
with IdiomaticMockitoFixture
with ScalaCheckPropertyChecks {
trait Setup {
val rectangle = mock[Rectangle]
val areaCalculator = new AreaCalculator(rectangle)
}
"AreaCalculator#printArea" should {
"should invoke area of the appropriate shape" in new Setup {
rectangle.getArea() shouldReturn 40.0
areaCalculator.printArea() mustBe true
}
}
}
Please check and suggest your valuable inputs. Let me know if any other details are required.
Thank you,
Rakesh Dhandhukiya
I had updated to latest compatible versions found in https://www.scalatest.org/plus/mockito/versions before raising it here.
Updating to latest versions caused other test cases to failed and hence kept to latest versions mentioned in above list.
However, failing test case in this sample code got resolved after updating versions as you suggested and replacing IdiomaticMockitoFixture. With latest versions also if we use IdiomaticMockitoFixture then still this test case fails.
Will check with actual application and update further. Thanks. – Rakesh D Jun 22 '22 at 14:39