Mockitoテストの基本的な使い方
20321 ワード
一、mockテストとは何ですか。mockオブジェクトとは何ですか。
まず、次の例を見てみましょう.
上の図からAをテストする場合は、まず依存ツリー全体、すなわちBCDEの例を構築する必要があることがわかります.
代替案はmocksを使うことです
図からはっきり見える
mockオブジェクトは、デバッグ中に実際のオブジェクトとして使用される代替品です.mockテストとは、テスト中に構築しにくいオブジェクトに対してテストの代わりに仮想オブジェクトを使用する方法をmockテストと呼びます.
mockテストとは何かを知ったら、mockフレームワーク-Mockitoを認識しましょう.
二、Mockitoとは
覚えやすい名前のほか、Mockitoは異なる方法でmockingテストを試み、EasyMockの代わりに簡単な軽量級のフレームワークである.簡単で、テストコードの可読性が高く、豊富なドキュメントがjavadocに含まれており、IDEで直接ドキュメント、インスタンス、説明を表示できます.詳細:http://code.google.com/p/mockito/
三、StubとMock
同じ点:StubオブジェクトとMockオブジェクトは外部依存をシミュレートするために使用され、制御できます.
異なる点:-stubは完全に外部依存をシミュレートし、テストに必要なテストデータを提供します.-mockオブジェクトは、テストが合格できるかどうかを判断するために使用されます.すなわち、テスト中の依存オブジェクト間のインタラクションが予想されるかどうかを検証するために使用されます.-mockingフレームワークでは、stubとmockの両方としてmockオブジェクトを同時に使用できますが、厳密な違いはありません.
詳細:http://martinfowler.com/articles/mocksArentStubs.html
四、mockito入門例
<dependency>
<groupId>org.mockitogroupId>
<artifactId>mockito-allartifactId>
<version>1.10.19version>
dependency>
@Test
@SuppressWarnings("unchecked")
public void testSimple() throws Exception {
// mock
/* mock final,Anonymous ,primitive mock。*/
List<String> list = mock(List.class);
//
when(list.get(0)).thenReturn("hello world!");
//doReturn("hello wolrd!").when(list).get(0);
//
when(list.get(1)).thenThrow(new RuntimeException("exception!"));
// void ( , donothing, dothrow runtime )
doNothing().doThrow(new RuntimeException("void exception")).when(list).clear();
list.clear();
list.clear();
verify(list, times(2)).clear();
String result = list.get(0);
//
verify(list).get(0);
//junit
Assert.assertEquals("hello world!", result);
}
Ps:mockオブジェクトを作成するにはfinal,Anonymous,primitiveクラスはmockできません.
五、パラメータ整合器(Argument Matcher)
Matchersクラスにはパラメータマッチング器anyInt、anyString、anyMapがたくさんあります.MockitoクラスはMatchersに継承され、Stubbingでは組み込みパラメータマッチングを使用します.次の例です.
/**
*
* , , stubbing verify 。
*/
@Test
@SuppressWarnings("unchecked")
public void argumentMatcherTest() throws Exception {
List<String> list = mock(List.class);
when(list.get(anyInt())).thenReturn("hello", "world", "hqq");
String result = list.get(0) + list.get(1);
verify(list, times(2)).get(anyInt());
Assert.assertEquals("helloworld", result);
Map<Integer, String> map = mock(Map.class);
when(map.put(anyInt(), anyString())).thenReturn("hello");
String str = map.put(1, "world");
verify(map).put(eq(1), eq("world"));
Assert.assertEquals("hello", str);
}
パラメータマッチングを使用する場合は、stubbingでもverifyでも、すべてのパラメータはパラメータマッチングを使用します.
六、メソッド呼び出しの検証(具体的な呼び出し回数、少なくとも一回、一度もない)
/**
*
*/
@Test
public void verifyInvocate() throws Exception {
List<String> list = mock(List.class);
list.add("one");
list.add("twice");
list.add("twice");
list.add("three times");
list.add("three times");
list.add("three times");
verify(list, times(1)).add("one");
verify(list, times(2)).add("twice");
verify(list, times(3)).add("three times");
verify(list, times(0)).add("never added");
verify(list, atLeastOnce()).add("one");
verify(list, atLeast(2)).add("twice");
verify(list, atMost(3)).add("three times");
}
七、順番に検証する
/**
*
*/
@Test
@SuppressWarnings("unchecked")
public void orderTest() throws Exception {
// A. mock 。
List singleMock = mock(List.class);
singleMock.add("first");
singleMock.add("second");
// Mock InOrder
InOrder inOrderSingle = inOrder(singleMock);
//
inOrderSingle.verify(singleMock).add("first");
inOrderSingle.verify(singleMock).add("second");
// B. mock
List firstMock = mock(List.class);
List secondMock = mock(List.class);
firstMock.add("first add");
secondMock.add("second add");
InOrder inOrderMulti = inOrder(firstMock, secondMock);
inOrderMulti.verify(firstMock).add("first add");
inOrderMulti.verify(secondMock).add("second add");
}
八、インタラクティブ操作がMockオブジェクト上で実行されていないことを確認する
// mock —— mockOne
mockOne.add("one");
//
verify(mockOne).add("one");
//
verify(mockOne, never()).add("two");
// Mock
verifyZeroInteractions(mockTwo, mockThree);
九、余分な呼び出しを探す
// mock
mockedList.add("one");
mockedList.add("two");
verify(mockedList).add("one");
//
verifyNoMoreInteractions(mockedList);
十、素早くmockオブジェクトを作成する——@Mock注記
@RunWith(MockitoJUnitRunner.class)
public class AnnotationMockTest {
@Mock
List list;
@Mock
private User user;
@Test
public void test() throws Exception {
when(list.get(0)).thenReturn("hello,mockito");
System.out.println(list.get(0));
}
@Test
public void userTest() throws Exception {
when(user.getName()).thenReturn("heqianqian");
System.out.println(user.getName());
}
}
十一、反復式のテスト
同じメソッドで呼び出された戻り値または異常のテスト杭が必要になる場合があります.典型的な運用はMock反復器の使用である.Mockitoの初期バージョンにはこの特性はありません.たとえば、開発者は反復器の代わりにIterableまたは簡単な集合を使用する場合があります.これらの方法は、テスト杭としてより自然な方法を提供し、いくつかのシーンでは、連続的な呼び出しのためにテスト杭として役立ちます.たとえば、次のようにします.
@RunWith(MockitoJUnitRunner.class)
public class IteratorMockitoTest {
@Mock
List list;
@Test
public void iteratorTest() throws Exception {
when(list.get(0)).thenReturn("one","two","three");
// one
System.out.println(list.get(0));
// two
System.out.println(list.get(0));
// three
System.out.println(list.get(0));
System.out.println(list.get(0));
}
}
十二、コールバックのために試験杭を作る
汎用インタフェースAnswerに杭を打つ.
public class CallbackMockitoTest {
@Test
@SuppressWarnings("unchecked")
public void callbackTest() throws Exception {
List list = mock(List.class);
list.add("hello");
when(list.get(0)).thenAnswer(new Answer() {
@Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
//
Object[] args = invocationOnMock.getArguments();
// Mock
Object mock = invocationOnMock.getMock();
return "called with arguments:" + args[0].toString();
}
});
System.out.println(list.get(0));
}
}
十三、真実の対象を監視する
実際のオブジェクトに対してモニタリング(spy)オブジェクトを作成できます.このspyオブジェクトを使用すると、この関数が杭打ちされない限り、実際の方法も呼び出されます.実際には、残されたコードを処理する場合など、節制されたspyオブジェクトが必要です.
List list = new LinkedList();
List spy = spy(list);
// :
when(spy.size()).thenReturn(100);
// spy :
spy.add("one");
spy.add("two");
// list
System.out.println(spy.get(0));
// size() , 100
System.out.println(spy.size());
//
verify(spy).add("one");
verify(spy).add("two");
モニタリング対象にwhen(Object)を用いて杭打ちを行うことは不可能または非現実的である場合がある.そこでspyを使うときはdoReturn|Answer|Throw()という一連の方法を考えて杭打ちをしてください.例:
List list = new LinkedList();
List spy = spy(list);
// : spy.get(0) get(0) , IndexOutOfBoundsException, list 。
when(spy.get(0)).thenReturn("foo");
// doReturn 。
doReturn("foo").when(spy).get(0);