Like MockitoSugar for ScalaTest, but sweeter and with fewer calories.
Inspired by the Mockito DSL in Specs2, adapted for use with ScalaTest
Available to download from jCenter
SBT:
libraryDependencies ++= Seq (
"com.github.jostly" %% "mockito-sweetener" % "0.3.0"
)
Maven:
<dependency>
<groupId>com.github.jostly</groupId>
<artifactId>mockito-sweetener_2.11</artifactId>
<version>0.3.0</version>
</dependency>
val m = mock[List[Int]]
m.length returns 17
assert(m.length == 17)
m.contains(any[Int]) returns true
assert(m.contains(5) == true)
val m = mock[List[Int]]
m.length
there was one(m).length
there was zero(m).head
val m = mock[List[Int]]
m.contains(3) returns true
assert(m.contains(3) == true)
assert(m.contains(5) == false)
m.contains(any[Int]) returns true
assert(m.contains(5) == true)
there was one(m).contains(lessThan(5))
there were two(m).contains(greaterThanOrEqual(5))
there were 3.of(m).contains(*)
You can use any ScalaTest matcher as a Mockito matcher.
import org.scalatest.Matchers._
val m = mock[List[Int]]
m(be < 3) returns 17
assert(m(1) == 17)
assert(m(2) == 17)
assert(m(3) == 0)
If the method you are mocking is generic, or takes AnyRef,
the implicit conversion might not kick in. Use the should
method in that case:
val m = mock[List[Int]]
m.contains(be < 3) returns true // will compile, but not work:
assert(m.contains(1) == false)
m.contains(should(be < 3)) returns true
assert(m.contains(1) == true)
Since ScalaTest matchers can be combined to form compound matches, they can be used to set up more complex expectations easily:
val m = mock[List[String]]
m(be > 0 and be < 10) returns "Single digit"
Mix in the Capturing
trait to enable argument capturing in verifications. All use of argument captures
must be wrapped in a capturing { ... }
block:
capturing {
// do your captures and verifications here
}
You can capture arguments to a named argument captor using the captured as "<label>"
argument matcher,
which will store captured arguments under the supplied label. Retrieve the captured arguments
using captured.get[<your type>](<the label>)
:
val probe = mock[Probe]
probe.single("foo")
capturing {
there was one(probe).single(captured as "a")
captured.get[String]("a") shouldBe "foo"
}
If there are multiple calls to your method, you can get all the captured values with
the captured.getAll
method.
If all you want to do is run verfications on the captured arguments, use the
verified.by(partial function)
construct:
val probe = mock[Probe]
probe.single("foo")
capturing {
there was one(probe).single(verified[String] by {
case s =>
s shouldBe "foo"
})
}
At the end of the capturing { ... }
block, the supplied partial function will be evaulated for
all captured values.
Mockito 2 requires at least Java 8 u45. If you see the following error when mocking generic types, you most likely need to update your JDK:
[info] org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: ...
[info]
[info] Mockito can only non-private & non-final classes.
[info] If you're not sure why you're getting this error, please report to the mailing list.
[info]
[info] Java 8 early builds have bugs that were addressed in Java 1.8.0_45, please update your JDK!
- Upgrade to Mockito 2.1.0
- Mockito is no longer an optional dependency
- Updated dependencies:
- Mockito
1.10.19
=>2.1.0
- Scala XML
1.0.5
=>1.0.6
- Mockito
- Added argument capturing with the
Capturing
trait
- Upgraded dependencies:
- ScalaTest
2.2.6
=>3.0.0
(motivating a minor version bump) - Mockito
1.9.0
=>1.10.19
- Scala XML
1.0.2
=>1.0.5
- Scala
2.11.7
=>2.11.8
- ScalaTest
- Removed debug printouts
- Slightly narrowed the specialization of
MockitoMatchers.is
- Added
zero
as an alias forno
in call number verifications to fix a conflict with ScalaTest Matchers
- Added specialization where necessary to properly handle cases of matching / stubbing primitives
- Initial release