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) {}
}
- Minimizes 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 { |
3 | @Mock private ArticleCalculator calculator; |
4 | @Mock private ArticleDatabase database; |
5 | @Mock private UserProvider userProvider; |
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()) |
05 | //First call: throws runtime exception: |
06 | mock.someMethod( "some arg" ); |
08 | //Second call: prints "foo" |
09 | System.out.println(mock.someMethod( "some arg" )); |
11 | //Any consecutive call: prints "foo" as well (last stubbing wins). |
12 | System.out.println(mock.someMethod( "some arg" )); |
You can create spies of real objects. When you use the spy then the
real
methods are called (unless a method was stubbed).
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)
01 | List list = new LinkedList(); |
04 | //optionally, you can stub out some methods: |
05 | when(spy.size()).thenReturn( 100 ); |
07 | //using the spy calls *real* methods |
11 | //prints "one" - the first element of a list |
12 | System.out.println(spy.get( 0 )); |
14 | //size() method was stubbed - 100 is printed |
15 | System.out.println(spy.size()); |
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()); |
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);
行为驱动开发
Behavior Driven Development style of writing tests uses //given //when //then comments as fundamental parts of your test methods. This is exactly how we write our tests and we warmly encourage you to do so! 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:
01 | import static org.mockito.BDDMockito.*; |
03 | Seller seller = mock(Seller. class ); |
04 | Shop shop = new Shop(seller); |
06 | public void shouldBuyBread() throws Exception { |
08 | given(seller.askForBread()).willReturn( new Bread()); |
11 | Goods goods = shop.buyBread(); |
14 | assertThat(goods, containBread()); |
|