test doubles and easymock

Post on 15-Apr-2017

148 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Tests Doubles &EasyMock

Created by Rafael Gutiérrez / / rgutierrez@nearsoft.com@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!

top related