mockito 很好mock框架
?
package com.zero.orzprofiler.mockito;import org.junit.Test;import java.util.*;import static org.mockito.Mockito.*;/** * User: luochao * Date: 14-1-3 * Time: 上午9:54 */public class MockitoTest { @Test public void testVerify() throws RuntimeException{ //mock create List mockedList = mock(List.class); mockedList.add("one"); mockedList.clear(); verify(mockedList).add("one"); verify(mockedList).clear(); when(mockedList.get(0)).thenReturn("l234");// when(mockedList.get(1)).thenThrow(new RuntimeException("runtime exception...")); System.out.println(mockedList.get(0)); System.out.println(mockedList.get(2)); System.out.println(mockedList.get(1)); List spyList = new LinkedList(); List spy = spy(spyList); spy.add("one"); when(spy.size()).thenReturn(100); verify(spy).add("one"); System.out.println(spy.size()); doReturn("lccx").when(spy).get(2); //verify(mockedList).add("two"); System.out.println(spy.get(2)); }}?timetunel初始化参数
package com.taobao.timetunnel.tunnel;import static java.lang.Thread.currentThread;import static org.hamcrest.Matchers.is;import static org.junit.Assert.assertThat;import static org.mockito.Mockito.doReturn;import java.nio.ByteBuffer;import java.util.Collections;import java.util.Iterator;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;import org.junit.Before;import org.junit.Test;import org.mockito.Mock;import com.taobao.timetunnel.InjectMocksSupport;import com.taobao.timetunnel.message.Message;import com.taobao.timetunnel.session.Attribute;import com.taobao.timetunnel.session.Session;import com.taobao.timetunnel.tunnel.ByteBufferMessageWatchers;import com.taobao.timetunnel.tunnel.Cursor;import com.taobao.timetunnel.tunnel.Group;import com.taobao.timetunnel.tunnel.Watchable;import com.taobao.timetunnel.tunnel.Watcher;import com.taobao.util.Bytes;/** * @{link WatcherTest} * @author <a href=mailto:jushi@taobao.com>jushi</a> * @created 2010-11-29 * */public class WatcherTest extends InjectMocksSupport { @Mock private Session session; @Mock public Message<ByteBuffer> message; private Watcher<ByteBuffer> watcher; private static final int TIMES = 10; private final FakeWatchable watchable = new FakeWatchable(); @Before public void setUp() throws Exception { doReturn(3).when(session).intValueOf(Attribute.receiveWindowSize); doReturn("dw").when(session).stringValueOf(Attribute.subscriber); doReturn(Bytes.toBuffer(0)).when(message).content(); watcher = new ByteBufferMessageWatchers(watchable).watcher(session); }@Test public void shouldAckedGetAndRefluxEqualsPushed() throws Exception { int ackedGet = 0; int size = 0; while (ackedGet + size < TIMES) { ackedGet += size; size = watcher.ackAndGet().size(); } watcher.dispose(); final int pushed = watchable.count.get(); assertThat(watchable.reflux + ackedGet, is(pushed)); } /** * @{link FakeWatchable} */ private final class FakeWatchable implements Watchable<ByteBuffer> { @Override public void onAvaliable(final Watcher<ByteBuffer> watcher) { new Thread(new Runnable() { @Override public void run() { fireOnMessageReceived(watcher); } }, "FireOnMessageReceivedTask").start(); } protected void fireOnMessageReceived(final Watcher<ByteBuffer> watcher) { System.out.println(currentThread().getName() + currentThread().getId()); for (;;) { final Iterator<Message<ByteBuffer>> itr = Collections.singleton(message).iterator(); final Cursor<Message<ByteBuffer>> cursor = new Cursor<Message<ByteBuffer>>() { @Override public Message<ByteBuffer> next() { if (itr.hasNext()) return itr.next(); return null; } }; watcher.onMessageReceived(cursor); if (itr.hasNext()) break; count.incrementAndGet(); } } private int reflux; private final AtomicInteger count = new AtomicInteger(); @Override public Group<ByteBuffer> groupOf(Watcher<ByteBuffer> watcher) { return new Group<ByteBuffer>() { @Override public void reclaim(Session session, List<Message<ByteBuffer>> reflux) { FakeWatchable.this.reflux += reflux.size(); } @Override public void dispose() {} }; } @Override public void onHasUselessMessages(Watcher<ByteBuffer> watcher) {}}
?
1.?Shorthand for mocks creation -?@Mock
?annotationMinimizes repetitive mock creation code.Makes the test class more readable.Makes the verification error easier to read because the?field name?is used to identify the mock.1
public
?class
?ArticleManagerTest {
2
??
?3
????
@Mock
?private
?ArticleCalculator calculator;
4
????
@Mock
?private
?ArticleDatabase database;
5
????
@Mock
?private
?UserProvider userProvider;
6
??
?7
????
private
?ArticleManager manager;
Important!?This needs to be somewhere in the base class or a test runner:1
MockitoAnnotations.initMocks(testClass);
when(mock.someMethod(
"some arg"
))
02
??
.thenThrow(
new
?RuntimeException())
03
??
.thenReturn(
"foo"
);
04
?05
//First call: throws runtime exception:
06
mock.someMethod(
"some arg"
);
07
?08
//Second call: prints "foo"
09
System.out.println(mock.someMethod(
"some arg"
));
10
?11
//Any consecutive call: prints "foo" as well (last stubbing wins).
12
System.out.println(mock.someMethod(
"some arg"
));
doReturn()
|doThrow()
|?doAnswer()
|doNothing()
|doCallRealMethod()
?family of methods?Real spies should be used?carefully and occasionally, for example when dealing with legacy code.
Spying on real objects can be associated with "partial mocking" concept.?Before the release 1.8, Mockito spies were not real partial mocks. The reason was we thought partial mock is a code smell. At some point we found legitimate use cases for partial mocks (3rd party interfaces, interim refactoring of legacy code, the full article is?here)
view sourceprint?01
List list =?
new
?LinkedList();
02
List spy = spy(list);
03
?04
//optionally, you can stub out some methods:
05
when(spy.size()).thenReturn(
100
);
06
?07
//using the spy calls *real* methods
08
spy.add(
"one"
);
09
spy.add(
"two"
);
10
?11
//prints "one" - the first element of a list
12
System.out.println(spy.get(
0
));
13
?14
//size() method was stubbed - 100 is printed
15
System.out.println(spy.size());
16
?17
//optionally, you can verify
18
verify(spy).add(
"one"
);
19
verify(spy).add(
"two"
);
//you can create partial mock with spy() method:???
2
List list = spy(
new
?LinkedList());
3
?4
//you can enable partial mock capabilities selectively on mocks:
5
Foo mock = mock(Foo.
class
);
6
//Be sure the real implementation is 'safe'.
7
//If real implementation throws exceptions or depends on specific state of the object then you're in trouble.
8
when(mock.someMethod()).thenCallRealMethod();
reset(mock);
行为驱动开发
Start learning about BDD here:?http://en.wikipedia.org/wiki/Behavior_Driven_Development
The problem is that current stubbing api with canonical role of?when?word does not integrate nicely with?//given //when //then?comments. It's because stubbing belongs to?given?component of the test and not to the?when?component of the test. Hence?BDDMockito
?class introduces an alias so that you stub method calls with?BDDMockito.given(Object)
?method. Now it really nicely integrates with the?given?component of a BDD style test!
Here is how the test might look like:
view sourceprint?01
import
?static
?org.mockito.BDDMockito.*;
02
?03
Seller seller = mock(Seller.
class
);
04
Shop shop =?
new
?Shop(seller);
05
?06
public
?void
?shouldBuyBread()?
throws
?Exception {
07
??
//given?
08
??
given(seller.askForBread()).willReturn(
new
?Bread());
09
??
?10
??
//when
11
??
Goods goods = shop.buyBread();
12
??
?13
??
//then
14
??
assertThat(goods, containBread());
15
}?
?