1

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:

  1. Shape.scala
    package mockito.sample
    
    trait Shape {

      final def printArea(): Unit = {
        println(s"Area is: $getArea()")
      }
    
      def getArea(): Double

    }
  1. Rectangle.scala
    package mockito.sample
    
    class Rectangle(l: Long, b: Long) extends Shape {

      override def getArea(): Double = {
        l * b
      }

    }
  1. AreaCalculator.scala
    package mockito.sample
    
    class AreaCalculator(shape: Shape) {

      def printArea(): Boolean = {
        shape.printArea()
        true
      }

    }
  1. 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

Alin Gabriel Arhip
  • 2,568
  • 1
  • 14
  • 24
Rakesh D
  • 13
  • 3

1 Answers1

1

How are you disabling the mock-maker-inline?

If you can update mockito and scalatest to the latest versions, this should go away: I tried reproducing the error but the test passes in my case.

It appears IdiomaticMockitoFixture is deprecated and you should use IdiomaticMockito.

However, I do get this warning when adding mock-maker-inline:

OpenJDK 64-Bit Server VM warning: Sharing is only supported for 
  boot loader classes because bootstrap classpath has been appended

It seems to be harmless though. I tried disabling my Instrumenting agent, but I still get it. (Removing mock-maker-inline makes the warning disappear)

Here's the code, a bit modified:

trait Shape {
  final def printArea(): Unit = println(s"Area is: $getArea")
  def getArea: Double
}

class Rectangle(l: Long, b: Long) extends Shape {
  override def getArea: Double = l * b
}

class AreaCalculator(shape: Shape) {
  def printArea(): Boolean = {
    shape.printArea()
    true
  }
}

AreaCalculatorSpec updated with the new dependencies:

import org.mockito.IdiomaticMockito
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 IdiomaticMockito
    with ScalaCheckPropertyChecks {

  trait Setup {
    val rectangle: 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
    }
  }
}

Setup for my mock-maker-inline:

enter image description here

My build.sbt:

libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.12" % Test
libraryDependencies += "org.scalamock" %% "scalamock" % "5.2.0" % Test
libraryDependencies += "org.scalatestplus" %% "scalacheck-1-16" % "3.2.12.0" % Test
libraryDependencies += "org.scalatestplus" %% "mockito-4-5" % "3.2.12.0" % Test
libraryDependencies += "org.mockito" % "mockito-core" % "4.6.1" % Test
libraryDependencies += "org.mockito" %% "mockito-scala" % "1.17.7" % Test
Alin Gabriel Arhip
  • 2,568
  • 1
  • 14
  • 24
  • 1
    Thanks @Alin for your reply.
    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
  • 1
    Thanks, it worked for actual application also. Need to resolve many compilation errors due to version update but finally it worked. Thank you once again !!! – Rakesh D Jun 23 '22 at 14:51