|
UsingEasyMock
Using EasyMock mocks.
IntroductionEasyMock is a mocking library: EasyMock provides Mock Objects for interfaces (and objects through the class extension) by generating them on the fly using Java's proxy mechanism. Due to EasyMock's unique style of recording expectations, most refactorings will not affect the Mock Objects. So EasyMock is a perfect fit for Test-Driven Development. specs integrates EasyMock expectations and add some syntactic sugar for an even simpler experience of EasyMock. UsageIn order to use EasyMock mocks in your specification, you need to mix in the EasyMock trait. Here is an example of EasyMock usage: import org.specs.Specification
import org.specs.mock.EasyMock
import org.easymock.EasyMock._ // to use matchers like anyInt()
object spec extends Specification with EasyMock {
class ToMock {
def voidMethod = ()
@throws(classOf[Exception])
def size = 1
def get(i: Int) = i.toString
}
val m = mock[ToMock] // this creates a "strict" mock
"This is the canonical way of using EasyMock" in {
m.voidMethod // declare expected mock calls
replay(m) // the mock needs to be replayed
m.voidMethod // use the mock
verify(m) // verify expectations
}Mocks creationEasyMock provides different methods to create mocks:
Mock methodsThere are many methods directly applicable to mocks instead of calling the corresponding EasyMock.(...) method:
Block replayIt is possible to replay all mocks: expect {
m1.method1
m2.method2
} // m1 and m2 are automatically replayed. This is equivalent to replay(m1, m2)VerificationThe verify method is used as you would do in EasyMock: verify(m1, m2, m3) In that case, there is no "block verify" method available because this wouldn't save much from a call to verify with several arguments. Returned valuesReturned values are specified using returns: m.get(1) returns "one" EasyMock makes a strong difference between mocks and stubs, stub calls not being checked by verify. If you just want method calls to be stubbed you can use stubReturn: m.get(1) stubReturns "one" Thrown exceptionsThrown exceptions are specified using throws: m.size throws new Exception("bad call") Consecutive callsYou can specify different consecutive returned values by appending thenReturns or thenThrows: m.get(1) returns "one" thenReturns "two"
m.get(2) throws new Exception("forbidden") thenReturns "999"CallbacksIn some rare cases, it is necessary to have the return value depend on the parameters passed to the mocked method: val mockedList = mock[List[String]]
mockedList.get(anyInt) answers { i => "The parameter is " + i.toString } In this case, the answers method can be used with either:
DelegatesCalls can also be delegated to another object implementing the same interface as the mocked object. Use the delegatesTo method to that purpose: m.get(1) delegatesTo new ToMock replay(m) m.get(1) must_== 1 Note that stubDelegates is also available when you just need to delegate returned values with no mock verification. Repeated callsThe syntax used to specify that repeated calls will occur on a mock object is the following:
|
Sign in to add a comment