I recently added a dependency on Specs2 to a project and noticed that some existing tests written with ScalaTest and Mockito failed. These tests passed again once Specs2 was removed. Why does this happen?
lazy val scalatestandspecscoexisting = Project(
id = "scalatest-and-specs-coexisting",
base = file("."),
settings = Project.defaultSettings ++
GraphPlugin.graphSettings ++
Seq(
name := "Scalatest-And-Specs-Coexisting",
organization := "com.bifflabs",
version := "0.1",
scalaVersion := "2.9.2",
// libraryDependencies ++= Seq(scalaTest, mockito) //Tests Pass, no-specs2
libraryDependencies ++= Seq(scalaTest, specs2, mockito) //Tests Fail
)
)
The tests that failed all used Mockito and all setup a mock method with two different parameters. One of the calls to the mock does not return value it was set up with. The example below fails. A further requirement was that type must be a Function1 (or have apply method).
import org.scalatest.FunSuite
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito.when
trait MockingBird {
//Behavior only reproduces when input is Function1
def sing(input: Set[String]): String
}
class MockSuite extends FunSuite with MockitoSugar {
val iWannaRock = Set("I wanna Rock")
val rock = "Rock!"
val wereNotGonnaTakeIt = Set("We're not gonna take it")
val no = "No! We ain't gonna take it"
test("A mock should match on parameter but isn't") {
val mockMockingBird = mock[MockingBird]
when(mockMockingBird.sing(iWannaRock)).thenReturn(rock)
//Appears to return this whenever any Set is passed to sing
when(mockMockingBird.sing(wereNotGonnaTakeIt)).thenReturn(no)
// Succeeds because it was set up last
assert(mockMockingBird.sing(wereNotGonnaTakeIt) === no)
// Fails because the mock returns "No! We ain't gonna take it"
assert(mockMockingBird.sing(iWannaRock) === rock)
}
}
Output:
[info] MockSuite:
[info] - A mock should match on parameter but isn't *** FAILED ***
[info] "[No! We ain't gonna take it]" did not equal "[Rock!]" (MockSuite.scala:38)
[error] Failed: : Total 1, Failed 1, Errors 0, Passed 0, Skipped 0
EDIT – according to Eric’s comment below, this is a bug in Specs2 ≤ 1.12.2. Should be fixed in 1.12.3.
It turns out that Specs2 redefines some of the behavior in Mockito in order to get by-name parameters to match.
Eric answered my question
From the Specs2 documentation
In order to get my tests to pass again, I did the opposite of what was suggested in the specs2 documentation and added Specs2 dependency after Mockito. I have not tried, but I would expect by-name parameter matching to fail.
My tests now pass