Mock your way with Mockito

Preview:

Citation preview

1© Copyright 2011 EMC Corporation. All rights reserved.

Mock your way with MockitoAre you mocking me ?

by Vitaly PolonetskyJune 2012

2© Copyright 2011 EMC Corporation. All rights reserved.

MockitoMocking framework that tastes really

good

http://code.google.com/p/mockito/

3© Copyright 2011 EMC Corporation. All rights reserved.

Agenda• Basics

• Main features

• Integration

• Demo

• Additional features

4© Copyright 2011 EMC Corporation. All rights reserved.

Basics• Stubbing• Verifing

5© Copyright 2011 EMC Corporation. All rights reserved.

How do you drink it ?

import static org.mockito.Mockito.*;

• Stub method calls– Prepare test cases– Can replace DBUnit (integration tests) for unit

tests

• Verify interactions– Verify method invocations

6© Copyright 2011 EMC Corporation. All rights reserved.

How do you drink it ? (cont.)• Let’s write a class with some logic:

public class ComplexStrategy {

public int compute1(Items list) { return list.get(0) + list.get(1); }

public int compute2(Items list) { return 2 * list.get(0); }

}

7© Copyright 2011 EMC Corporation. All rights reserved.

Stub method calls// Mock interfaces or concrete classes

Items list = mock(Items.class);

// Stubbing

when(list.get(0)).thenReturn(5);

when(list.get(1)).thenReturn(7);

// Calling method that causes interaction with the mock

int result = complexStrategy.compute1(list);

// Test assertions

Assert.assertEquals(5 + 7, result);

By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, ... for int/Integer, boolean/Boolean, ...).

8© Copyright 2011 EMC Corporation. All rights reserved.

Verify interactions// Mock interfaces or concrete classes

Items list = mock(Items.class);

// Stubbing

when(list.get(0)).thenReturn(1);

// Calling method that causes interaction with the mock

int result = complexStrategy.compute1(list);

// Test interactions

verify(list).get(0);

• Once created, mock will remember all interactions. Then you can selectively verify whatever interaction you are interested in.

9© Copyright 2011 EMC Corporation. All rights reserved.

Difference in stubbing and verifying method arguments• Stubbing:

Method call inside when() call

when(mock.method(args)).then…

• Verifying:Method call outside of verify() call

verify(mock).method(args)

10© Copyright 2011 EMC Corporation. All rights reserved.

Main features• Argument matchers• Number of interactions and

invocations• Annotations• Methods returning void

11© Copyright 2011 EMC Corporation. All rights reserved.

Argument matcherswhen(svc.get("someId")).then…

• The default matching of the passed argument “someId” is using the equals() method

• To introduce smart matcher, you can use the org.hamcrest.Matcher interface and the classes that implement it:when(svc.get(any()).then…when(svc.get(argThat(matcher))).then…

• At the same stub setup, you should either declare all arguments as plain objects, or all of them using matchersIf you need to combine, you can use the eq() matcher

12© Copyright 2011 EMC Corporation. All rights reserved.

Argument matchers (cont.)• Mockito class provides many built-in matchers, some of

them:– eq(), any(), isA(), isNull(), notNull()– anyInt(), anyBoolean(), anyFloat()– anyString(), contains(), startsWith(), endsWith(), matches()

– anyCollection(), anyList(), anyMap(), anySet()– refEq()

• And type-safe matcher wrappers:– argThat()– intThat(), booleanThat(), floatThat()

• Other matchers in AdditionalMatchers class:– and(), or(), not(), gt(), lt(), geq(), leq()– aryEq(), cmpEq()

13© Copyright 2011 EMC Corporation. All rights reserved.

Verify number of invocations• Invoked once:

– verify(mockedList).add("once");– verify(mockedList, times(1)).add("once");

• Invoked exactly x times:– verify(mockedList, times(2)).add("twice");– verify(mockedList, times(3)).add("three times");

• Never:– verify(mockedList, never()).add("never happened");– verify(mockedList, times(0)).add("never happened");

• At least / at most:– verify(mockedList, atLeastOnce()).add("three times");

– verify(mockedList, atLeast(2)).add("five times");– verify(mockedList, atMost(5)).add("three times");

14© Copyright 2011 EMC Corporation. All rights reserved.

Check no interactions with mock• No interactions at all:

verifyZeroInteractions(someMock);

• No redundant invocations:verify(mockedList).add("one");verifyNoMoreInteractions(mockedList);

• Use of verify(mock, never()) is preferred, no interactions with mock should be checked rarely

15© Copyright 2011 EMC Corporation. All rights reserved.

@Mock annotation• Minimizes repetitive mock creation code

• Makes the test class more readable

• Makes the verification error easier to read (field name is shown)

public class ArticleManagerTest {

@Mock private ArticleCalculator calculator;

@Mock private ArticleDatabase database;

@Mock private UserProvider userProvider;

private ArticleManager manager; …}

MockitoAnnotations.initMocks(articleManagerTestObj);

16© Copyright 2011 EMC Corporation. All rights reserved.

Stubbing void methodswhen(svc.noReturn()).then…

• Oops, you can’t use the response from noReturn()

• Use this instead:– doThrow(new RuntimeException())

.when(svc)

.noReturn();

• Other methods:– doReturn(Object)– doThrow(Throwable)– doThrow(Class)– doAnswer(Answer)– doNothing()– doCallRealMethod()

17© Copyright 2011 EMC Corporation. All rights reserved.

Spying• Unfortunately some classes are loosely coupled with no interface, in this

case we can spy on real objects:List list = new LinkedList();List spy = spy(list);

//optionally, you can stub out some methods:when(spy.size()).thenReturn(100);

//using the spy calls *real* methodsspy.add("one");spy.add("two");

//prints "one" - the first element of a listSystem.out.println(spy.get(0));

//size() method was stubbed - 100 is printedSystem.out.println(spy.size());

//optionally, you can verifyverify(spy).add("one");verify(spy).add("two");

18© Copyright 2011 EMC Corporation. All rights reserved.

Spying (cont.)• Sometimes when(Object) can’t be used to stub spies.

In these cases doReturn()/doAnswer()/doThrow() family of methods should be used.

List list = new LinkedList();List spy = spy(list);

//real method is called, throws IndexOutOfBoundsExceptionwhen(spy.get(0)).thenReturn("foo");

• Passed real instance is not used, a copy of it is created. Therefore you should not interact with the real instance.

• Final methods can’t be mocked and/or verified. DUH!!!

19© Copyright 2011 EMC Corporation. All rights reserved.

@Spy and @InjectMocks annotations• @Spy – instead of spy(Object)

• @InjectMocks – injects mock or spy fields into tested object automatically

• Initialization using:MockitoAnnotations.initMocks(Object)

• Automatic instantiation of @Spy and @InjectMocks://instead:@Spy BeerDrinker drinker = new BeerDrinker();//you can write:@Spy BeerDrinker drinker;

//same applies to @InjectMocks annotation:@InjectMocks LocalPub pub;

20© Copyright 2011 EMC Corporation. All rights reserved.

Integration• Straight forward using Spring• JUnit runner

21© Copyright 2011 EMC Corporation. All rights reserved.

Integration using Spring• Simple XML initialization:

<bean id="dao" class="org.mockito.Mockito" factory-method="mock">    <constructor-arg value="com.package.Dao" /></bean>

• Spring XML initialization with autowiring support:<bean id="dao" class="org.springframework.aop.framework.ProxyFactoryBean">   <property name="target"> <bean class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="com.package.Dao" /> </bean> </property>   <property name="proxyInterfaces"> <value>com.package.Dao</value> </property></bean>

• Springockito:<mockito:mock id="dao" class="com.package.Dao" />

22© Copyright 2011 EMC Corporation. All rights reserved.

JUnit Runner• Mocks are the base of unit tests, so Mockito

provides JUnit runner out of the box:@RunWith(MockitoJUnitRunner.class)public class MyTest { …}

• Initializes annotations in the test class

• Bake the mock differently for each test

23© Copyright 2011 EMC Corporation. All rights reserved.

Demo• PolicyProviderSinglePolicyTest• AABOAuthenticationProviderTest

24© Copyright 2011 EMC Corporation. All rights reserved.

Additional features

25© Copyright 2011 EMC Corporation. All rights reserved.

Additional features• Verifying order of invocations

InOrder inOrder = inOrder(mock);inOrder.verify(…inOrder.verify(…

• Stubbing consecutive callswhen(mock.someMethod())

.thenThrow(new RuntimeException())

.thenReturn("foo");

• Stubbing with callbacks– add implementation to mock method

26© Copyright 2011 EMC Corporation. All rights reserved.

Additional features (cont.)• Capturing arguments and @Captor

• Real partial mocks:– Spy is one kind of partial mock– Another option is to use:when(mock…).thenCallRealMethod();

• Resetting mocks – make mock forget about interactions & stubbing (poorly written test):reset(mock);

• Verification with timeout

27© Copyright 2011 EMC Corporation. All rights reserved.

Additional features (cont.)• One-liner stubs:

Car boringStubbedCar = when(mock(Car.class).shiftGear()).thenThrow(EngineNotStarted.class).getMock();

• Mocking details:– Mockito.mockingDetails(someObject).isMock();

– Mockito.mockingDetails(someObject).isSpy();

28© Copyright 2011 EMC Corporation. All rights reserved.

THANK YOUTHANK YOU

Recommended