package
borachio
Type Members
-
-
-
-
-
case class
ExpectationException
(msg: String) extends RuntimeException with Product with Serializable
-
class
MatchAny
extends Equals
-
-
trait
Mock
extends AnyRef
-
-
class
MockFunction0
[R]
extends MockFunction with () ⇒ R
-
class
MockFunction1
[T1, R]
extends MockFunction with (T1) ⇒ R
-
class
MockFunction10
[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]
extends MockFunction with (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) ⇒ R
-
class
MockFunction2
[T1, T2, R]
extends MockFunction with (T1, T2) ⇒ R
-
class
MockFunction3
[T1, T2, T3, R]
extends MockFunction with (T1, T2, T3) ⇒ R
-
class
MockFunction4
[T1, T2, T3, T4, R]
extends MockFunction with (T1, T2, T3, T4) ⇒ R
-
class
MockFunction5
[T1, T2, T3, T4, T5, R]
extends MockFunction with (T1, T2, T3, T4, T5) ⇒ R
-
class
MockFunction6
[T1, T2, T3, T4, T5, T6, R]
extends MockFunction with (T1, T2, T3, T4, T5, T6) ⇒ R
-
class
MockFunction7
[T1, T2, T3, T4, T5, T6, T7, R]
extends MockFunction with (T1, T2, T3, T4, T5, T6, T7) ⇒ R
-
class
MockFunction8
[T1, T2, T3, T4, T5, T6, T7, T8, R]
extends MockFunction with (T1, T2, T3, T4, T5, T6, T7, T8) ⇒ R
-
class
MockFunction9
[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]
extends MockFunction with (T1, T2, T3, T4, T5, T6, T7, T8, T9) ⇒ R
-
-
Borachio: Native Scala mocking
To use Borachio with ScalaTest, mix the com.borachio.scalatest.MockFactory trait into a Suite:
To use Borachio with JUnit3, mix the com.borachio.junit3.MockFactory trait into a TestCase:
Borachio supports two different mocking styles - Functional mocking and Proxy mocking.
Functional mocking
Functional mocks are created with
mockFunction. The following, for example, creates a mock function taking a singleIntargument and returning aString:Expectations then can be set on a mock function. The following, for example, says that we expect our mock to be called once with the argument
42, and that when called like that it should return the value"Forty two":Proxy mocking
Proxy mocks are created with
mock. The following, for example, creates a mock which implements all theTurtletrait (interface):Expectations can then be set on each of the methods within those traits. For example:
By default, an expectation accepts any arguments and a single call. The following two statements are equivalent:
As a convenience, proxy mocks also support the
stubsmethod. The following two statements are equivalent:Expectations
Expectations can be set on the arguments a function or method is called with and how many times it should be called. In addition, mocks can be instructed to return a particular value or throw an exception when that expectation is met.
Arguments
To specify expected arguments for a functional mock, use
expects. To specify expected arguments for a proxy mock, usewithArgsorwithArguments.If no expected arguments are given, mocks accept any arguments.
To specify arguments that should simply be tested for equality, provide the expected arguments as a tuple:
m expects ("this", "that")Borachio currently supports two types of generalized matching: wildcards and epsilon matching.
Wildcards
Wildcard values are specified with an
*(asterisk). For example:m expects ("this", *)will match any of the following:
m("this", 42) m("this", 1.0) m("this", null)Epsilon matching
Epsilon matching is useful when dealing with floating point values. An epsilon match is specified with the
~(tilde) operator:will match:
but will not match:
Predicate matching
More complicated argument matching can be implemented by passing a predicate; a function that takes a scala.Product and returns a
Boolean. For mock functions, useexpectsWhere:m = mockFunction[Double, Double, Unit] m expectsWhere { (x: Double, y: Double) => x < y }For proxy mocks, use
where:m = mock[Turtle] m expects 'setPosition where { (x: Double, y: Double) => x < y }Return value
Mocks can be instructed to return a specific value with
returnsorreturning:m1 returns 42 m2 expects ("this", "that") returning "the other"If no return value is specified, functional mocks return
null.asInstanceOf[R]whereRis the return type (which equates to0forInt,0.0forDoubleetc.).If no return value is specified, proxy mocks return
null. This works correctly for most return types, but not for methods returning primitive types (Int,Doubleetc.), where returningnullleads to aNullPointerException. So you will need to explicitly specify a return value for such methods. This restriction may be lifted in the future.You can return a computed value (or throw a computed exception) with
onCall, for example:val mockIncrement = mockFunction[Int, Int] m expects (*) onCall { x: Int => x + 1 }Exceptions
Instead of a return value, a mock can be instructed to throw:
m expects ("this", "that") throws new RuntimeException("what's that?")Call count
By default, mocks expect one or more calls (i.e. only fail if the function or method is never called). An exact number of calls or a range can be set with
repeat:There are various aliases for common expectations and styles:
m1 expects ("this", "that") once m2 returns "foo" noMoreThanTwice m3 expects (42) repeated 3 timesFor a full list, see Expectation.
Ordering
By default, expectations can be satisfied in any order. For example:
A specific sequence can be enforced with
inSequence:inSequence { m expects (1) m expects (2) } m(2) // throws ExpectationException m(1)Multiple sequences can be specified. As long as the calls within each sequence happen in the correct order, calls within different sequences can be interleaved. For example:
val m1 = mock[Turtle] val m2 = mock[Turtle] inSequence { m1 expects 'setPosition withArguments (0.0, 0.0) m1 expects 'penDown m1 expects 'forward withArguments (10.0) m1 expects 'penUp } inSequence { m2 expects 'setPosition withArguments(1.0, 1.0) m2 expects 'turn withArguments (90.0) m2 expects 'forward withArguments (1.0) m2 expects 'getPosition returning (2.0, 1.0) } m2.setPosition(1.0, 1.0) m1.setPosition(0.0, 0.0) m1.penDown m2.turn(90.0) m1.forward(10.0) m2.forward(1.0) m1.penUp expect((2.0, 1.0)) { m2.getPosition }To specify that there is no constraint on ordering, use
inAnyOrder(there is an implicitinAnyOrderat the top level). Calls toinSequenceandinAnyOrdercan be arbitrarily nested. For example:m expects 'a inSequence { m expects 'b inAnyOrder { m expects 'c inSequence { m expects 'd m expects 'e } m expects 'f } m expects 'gDebugging
If faced with a difficult to debug failing expectation, consider mixing one or both of the VerboseErrors or CallLogging traits into your test suite: