Tests Doubles &EasyMock
Created by Rafael Gutiérrez / / [email protected]@abaddon_gtz
May 2016, JVMMX @ Nearsoft
EasyMockEasyMock is the �rst dynamic Mock Object generator,
relieving users of hand-writing Mock Objects, or generatingcode for them.
Mock?What is a Mock?
Are you mocking me?
Mock
WikipediaIn object-oriented programming, mock objects are simulatedobjects that mimic the behavior of real objects in controlled
ways.
Googling: Mocks Aren't Stubs - Martin Fowler"However to fully understand the way people use mocks it is
important to understand mocks and other kinds of testdoubles."
What is a Test Double!?Mocks and now Test Doubles!, really?!
Test DoublesThey are also known as: Imposters.
SUT is a System under test.
DOC is a Depended-on Component.
Tests Doubles are like Stunt Doubles in �lming industry.
The movie is the SUT and the leading actor is the real DOC.
Why do you need a test double?Basically, to isolate the code you want to test from its
surroundings
Speed up test executionA test double’s implementation is often faster to execute than
the real thing.
A complex algorithm could take minutes to run, and minutesis FOREVER when we as developers want immediate
feedback by running automated tests.
You have to test those slow algorithms somewhere but noteverywhere.
Make execution deterministicWhen your code (and tests) is deterministic, you can run your
tests repeatedly againts the same code and you will alwaysget the same result.
What happen when your code has nondeterministicbehaviour: random behaviour, time-depending behaviour?
Test doubles can lend a hand with these kinds of sources fornondeterministic behavior.
Simulating special conditionsThere is always some conditions we can’t create using just the
APIs and features of our production code.
This happens when our code depends on a third party API,internet connection, an speci�c �le in some location, etc, etc.
Exposing hidden informationWhat information? information about the interactions
between the code under test and its collaborators.
Encapsulation and information hiding is a good thing in yourcode but complicates testing.
You could (please don't!) add methods for testing purposes toyour production code. By substituting a test double for thereal implementation, you can add code for-testing-only and
avoid littering your production code.
Types of Test Doubles
Wait, before it is important to understand
Test Stub (I)Also known as: Stub
With a Test Stub we can verify logic independently when theSUT depends on indirect inputs from other software
components.
We use a Test Stub when we need to control the indirectinputs of the SUT.
Test Stub (II)There some variations:
A Responder is used to inject valid indirect inputs into theSUT.
A Saboteur is used to inject invalid indirect inputs into theSUT.
Other variations: Temporary Test Stub, Procedural Test Stub& Entity Chain Snipping
Test Spy (I)Also know as: Spy or Recording Test Stub
With a Test Spy we can verify logic independently when theSUT has indirect outputs to other software components.
We use a Test Spy as an observation point to capture theindirect outputs for later veri�cation.
Test Spy (II)There some variations:
Retrieval Interface is a Test Spy with an interface speci�callydesigned to expose the recorded information.
Self Shunt collapses the Test Spy and the Testcase Class intoa single object. When SUT calls DOC it is actually calling
methods in the Testcase Object.
Other variations: Inner Test Double & Indirect OutputRegistry
Mock Object (I)With a Mock Object we can implement Behaviour
Veri�cation on the SUT.
We con�gure the Mock Object with the expected methodcalls and values with it should respond.
When exercising the SUT the Mock Object compares theactual with the expected arguments and method calls and
fails if they do not match.
No need for assertions in the test method!
Mock Object (II)Mocks could be strict or nice.
Strict Mocks if the calls are received in a different order thanthe expected. Nice Mocks tolerates out-of-order calls.
Tests written using Mock Objects look different because allthe expected behavior must be speci�ed before the SUT is
exercised.
Fake Object (I)Also know as: Dummy
We use a Fake Object to replace the component the SUTdepends with a much lighter-weight implementation.
The Fake Object only needs to provide the equivalentservices the real DOC provides.
Fake Object (II)There some variations:
Fake Databases replace the persistent layer with a FakeObject that is functionally equivalent. When replacing the
database with in-memory HashTables or Lists.
In-Memory Database is a Dummy database with a small-footprint functionality.
Other variations: Fake Web Service & Fake Service Layer
EasyMock by Example
Create a Mock Object1. Create Mock Object
static <T> T EasyMock.mock(Class<T> toMock)
2. Record the expected behaviour
3. Switch the Mock Object to replay state
Example: UserServiceImplFindByIdTest
Strick MocksWhen using EasyMock.mock() the order of method calls is
not checked.
Use EasyMock.strictMock() to create a Mock Objectthat check the order of method calls.
Example: UserServiceImplActivateTest
Nice MocksMock Objects created with EasyMock.mock() will throw
AssertionError for all unexpected calls.
A Nice Mocks allows all method calls and returns appropriateempty values (0, null, false) for unexpected method calls.
Example: PaymentServiceImplChargeTest
ExpectationsIn Record state the Mock Object does not behave like Mock
Object, but it records method calls.
Only after calling replay(), it behaves like Mock Objectchecking whether the expected method class are really done.
This means that in record state is where we specify what weexpect from the Mock Object.
Behavior of method callsUse:
To return a IExpectationSetters which we can use tosetting expectations for an associated expected invocation.
static <T> IExpectationSetters<T> expect(T value) static <T> IExpectationSetters<T> expectLastCall()
IExpectationSetters to answer,return or throw something
IExpectationSetters<T> andAnswer(IAnswer<? extends T> answer) IExpectationSetters<T> andReturn(T value) IExpectationSetters<T> andThrow(Throwable throwable)
Example:IExpectationSettersToAnswerReturnOrThrowTest
IExpectationSetters to stubresponses
We stub to respond to some method calls, but we are notinterested in how often they are called, when they are called,
or even if they are called at all.
IExpectationSetters<T> andStubAnswer(IAnswer<? extends T> answer) IExpectationSetters<T> andStubReturn(T value) IExpectationSetters<T> andStubThrow(Throwable throwable)
Example: IExpectationSettersToStubTest
IExpectationSetters to specify thenumber of calls and verify()
In EasyMock:
IExpectationSetters<T> times(int count) IExpectationSetters<T> times(int min, int max) IExpectationSetters<T> once() IExpectationSetters<T> atLeastOnce() IExpectationSetters<T> anyTimes()
static void verify(Object... mocks)
Example: IExpectationSettersNumCallsTest
Expectations with Argument MatchersObject arguments are compared using equals() when
matching method calls in Mock Objects.
This could lead to some issues or maybe we could need amore �exible way to match method calls.
EasyMock class contains a lot of prede�ned argumentmatchers for us to use!
Example: EasyMockArgumentMatchersTest
Capturing ArgumentsYou can capture the arguments passed to Mock Objects.
In EasyMock
static <T> T capture(Capture<T> captured) static x captureX(Capture<X> captured) // for primitives
Matches any value and captures it in the Capture parameterfor later access. You can also specify a CaptureType tellingthat a given Capture should keep the �rst, the last, all or no
captured values.
Example: CapturingArgumentsTest
Mocks concrete Objects?Yes!
Thanks!