Upload
vitaly-polonetsky
View
120
Download
0
Embed Size (px)
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