mockito-scala icon indicating copy to clipboard operation
mockito-scala copied to clipboard

Session fails if tests override the default executionContext

Open DaveDeCaprio opened this issue 3 years ago • 0 comments

I have a test suite that overrides the executionContext, replacing serialExecutionContext with the scala default global executionContext.

This leads to transient errors because of MockitoSessionAsyncFixture.withFixture. This function calls session.finishMocking inside result.onOutcomeThen, which uses the implicit executionContext for the suite.

The problem is that finishMocking needs to be called from the same thread in which the MockitoScalaSession was called. This is due to listeners being stored in a thread-local variable. As long as you are using serialExecutionContext this happens naturally, but not if you use an actual multithreaded execution context.

In my case I was able to work around it by leaving the suite execution context the same and overriding the ec in different tests.

The resulting exception when this happens is:

Unfinished mocking session detected. Previous MockitoSession was not concluded with 'finishMocking()'. For examples of correct usage see javadoc for MockitoSession class. org.mockito.exceptions.misusing.UnfinishedMockingSessionException: Unfinished mocking session detected. Previous MockitoSession was not concluded with 'finishMocking()'. For examples of correct usage see javadoc for MockitoSession class. at ai.closedloop.lagom.ExampleServiceStreamingSpec.withFixture(ExampleServiceStreamingSpec.scala:13) at org.scalatest.wordspec.AsyncWordSpecLike.invokeWithAsyncFixture$1(AsyncWordSpecLike.scala:1060) at org.scalatest.wordspec.AsyncWordSpecLike.$anonfun$runTest$1(AsyncWordSpecLike.scala:1074) at org.scalatest.AsyncSuperEngine.runTestImpl(AsyncEngine.scala:374) at org.scalatest.wordspec.AsyncWordSpecLike.runTest(AsyncWordSpecLike.scala:1074) at org.scalatest.wordspec.AsyncWordSpecLike.runTest$(AsyncWordSpecLike.scala:1054) at ai.closedloop.lagom.ExampleServiceStreamingSpec.org$scalatest$BeforeAndAfterEach$$super$runTest(ExampleServiceStreamingSpec.scala:13) at org.scalatest.BeforeAndAfterEach.runTest(BeforeAndAfterEach.scala:234) at org.scalatest.BeforeAndAfterEach.runTest$(BeforeAndAfterEach.scala:227) at ai.closedloop.lagom.ExampleServiceStreamingSpec.runTest(ExampleServiceStreamingSpec.scala:13) at org.scalatest.wordspec.AsyncWordSpecLike.$anonfun$runTests$1(AsyncWordSpecLike.scala:1133) at org.scalatest.AsyncSuperEngine.$anonfun$runTestsInBranch$3(AsyncEngine.scala:435) at org.scalatest.Status.$anonfun$thenRun$1(Status.scala:227) at org.scalatest.Status.$anonfun$thenRun$1$adapted(Status.scala:225) at org.scalatest.Status$.executeQueue(Status.scala:417) at org.scalatest.ScalaTestStatefulStatus.setCompleted(Status.scala:600) at org.scalatest.Status.$anonfun$thenRun$2(Status.scala:237) at org.scalatest.Status.$anonfun$thenRun$2$adapted(Status.scala:228) at org.scalatest.Status$.executeQueue(Status.scala:417) at org.scalatest.ScalaTestStatefulStatus.setCompleted(Status.scala:600) at org.scalatest.Status.$anonfun$withAfterEffect$1(Status.scala:389) at org.scalatest.Status.$anonfun$withAfterEffect$1$adapted(Status.scala:373) at org.scalatest.Status$.executeQueue(Status.scala:417) at org.scalatest.ScalaTestStatefulStatus.setCompleted(Status.scala:600) at org.scalatest.FutureAsyncOutcome.$anonfun$new$1(AsyncOutcome.scala:45) at org.scalatest.FutureAsyncOutcome.$anonfun$new$1$adapted(AsyncOutcome.scala:39) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64) at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

DaveDeCaprio avatar Feb 05 '22 15:02 DaveDeCaprio