Mockitoの浅談

11334 ワード

Mockitoの浅談


[TOC]

Mockitoの概要

  • mockとは何ですか?ソフトウェア開発の世界の外で、「mock」という言葉は模倣や模倣を指す.したがって、「mock」は、身代わり、代替者として理解することができる.ソフトウェア開発では「mock」と言及しており、通常はシミュレーションオブジェクトまたはFakeと理解されている.
  • なぜMockが必要なのですか?Mockはunits間の結合により試験が困難な問題を解決するためである.だからmock objectはunit testの一部です.

  • Mockのメリットは何ですか?

  • 事前作成テスト、TDD(テストドライバ開発)
  • これは最大のメリットでしょう.Mockを作成すると、サービスインタフェースを作成する前にService Testsを書くことができます.これにより、開発中に自動化されたテスト環境にテストを追加することができます.言い換えれば、シミュレーションはテスト駆動開発を使用することができます.
  • チームは、
  • を並列に作業できます.
    これは上の点に似ています.存在しないコードのテストを作成します.しかし、開発者がテストプログラムを作成することについては、テストチームが作成することについて説明しています.まだ測定するものがない場合、テストチームはどのようにテストを作成しますか?シミュレーションとシミュレーションテスト!これは、サービスがテストを必要とすると言い訳した場合、実際にQAチームには完全なテストコンポーネントがあります.1つのチームが別のチームの完了を待つことはありません.これにより,シミュレーションの効率型が特に際立った.
  • 検証プログラムまたはデモプログラムを作成できます.

  • Mocksは非常に効率的であるため、概念証明書を作成したり、概略図として使用したり、プロジェクトの構築を検討しているデモプログラムとして使用したりすることができます.これは、プロジェクトが次に行うかどうかを決定するために強力な基礎を提供していますが、最も重要なのは実際の設計決定を提供しています.
  • アクセスできないリソースの作成テスト
  • このメリットは実際の利益の1つではなく、必要なときの「救命圏」として使われています.このような状況に遭遇しましたか?サービスインタフェースをテストしたい場合、サービスはファイアウォールを介してアクセスする必要があります.ファイアウォールは開くことができません.または、認証が必要です.このような場合、アクセス可能な場所でMockServiceの代わりにMockServiceを使用することができます.これが「救命圏」機能です.
  • Mockは、ユーザ
  • に渡すことができる.
    場合によっては、パートナーやお客様などの外部ソースからテストシステムにアクセスできるようにする必要があります.これらの理由により、他の人も機密情報にアクセスできますが、一部のテスト環境にアクセスできるようにしたいだけかもしれません.この場合、パートナーまたはお客様にテストシステムを提供して、開発またはテストを行うにはどうすればいいですか?最も簡単なのは、あなたのネットワークやお客様からのネットワークにかかわらず、mockを提供することです.soapUI mockは構成が簡単で、soapUIを実行したり、warパッケージとしてjavaサーバに公開したりすることができます.
  • 隔離システム
  • システムの他の部分の影響なしにシステムの個別の一部をテストしたい場合があります.他のシステム部分はテストデータに干渉するため,データ収集によるテスト結論に影響する.mockを使用すると、テスト部分を必要とするシステム依存のシミュレーションを削除することができます.これらのmocksを分離すると、mocksは非常に簡単で信頼性が高く、迅速に予見できるようになる.これにより、ランダムな動作が削除され、重複モードがあり、特殊なシステムのテスト環境を監視することができます.

    Mockitoの使用例


    シミュレーションオブジェクト

    //  LinkedList    
    LinkedList mockedList = mock(LinkedList.class);
    //  get , null, 
    System.out.println(mockedList.get(0));  
    

    シミュレーションメソッド呼び出しの戻り値

    //  , first。   stub。
    when(mockedList.get(0)).thenReturn("first");
    //  first
    System.out.println(mockedList.get(0));  
    

    シミュレーションメソッド呼び出し放出例外

    //  , RuntimeException  
    when(mockedList.get(1)).thenThrow(new RuntimeException());
    //  RuntimeException  
    System.out.println(mockedList.get(1)); 
    

    関数に値タイプが返されていない場合は、このメソッドを使用して例外放出をシミュレートできます.
    doThrow(new RuntimeException("clear exception")).when(mockedList).clear();
    mockedList.clear();
    

    シミュレーション呼び出しメソッド時のパラメータマッチング

    // anyInt() int , , element  
    when(mockedList.get(anyInt())).thenReturn("element");
    //  element
    System.out.println(mockedList.get(999)); 
    

    シミュレーションメソッド呼び出し回数

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

    けんさどうさ

     // mock creation
     List mockedList = mock(List.class);
     // using mock object
     mockedList.add("one");
     mockedList.clear();
     //verification
     verify(mockedList).add("one");
     verify(mockedList).clear();
    

    シミュレーションメソッド呼び出し(Stubbing)

     //You can mock concrete classes, not just interfaces
     LinkedList mockedList = mock(LinkedList.class);
     //stubbing
     when(mockedList.get(0)).thenReturn("first");
     when(mockedList.get(1)).thenThrow(new RuntimeException());
     //following prints "first"
     System.out.println(mockedList.get(0));
     //following throws runtime exception
     System.out.println(mockedList.get(1));
     //following prints "null" because get(999) was not stubbed
     System.out.println(mockedList.get(999));
     
     verify(mockedList).get(0);
    

    パラメータマッチング

     //stubbing using built-in anyInt() argument matcher
     when(mockedList.get(anyInt())).thenReturn("element");
     //stubbing using custom matcher (let's say isValid() returns your own matcher implementation):
     when(mockedList.contains(argThat(isValid()))).thenReturn("element");
     //following prints "element"
     System.out.println(mockedList.get(999));
     //you can also verify using an argument matcher
     verify(mockedList).get(anyInt());
     //argument matchers can also be written as Java 8 Lambdas
     verify(mockedList).add(someString -> someString.length() > 5);
    

    チェックメソッド呼び出し回数

     //using mock
     mockedList.add("once");
     
     mockedList.add("twice");
     mockedList.add("twice");
     
     mockedList.add("three times");
     mockedList.add("three times");
     mockedList.add("three times");
     //following two verifications work exactly the same - times(1) is used by default
     verify(mockedList).add("once");
     verify(mockedList, times(1)).add("once");
     //exact number of invocations verification
     verify(mockedList, times(2)).add("twice");
     verify(mockedList, times(3)).add("three times");
     //verification using never(). never() is an alias to times(0)
     verify(mockedList, never()).add("never happened");
     //verification using atLeast()/atMost()
     verify(mockedList, atLeastOnce()).add("three times");
     verify(mockedList, atLeast(2)).add("five times");
     verify(mockedList, atMost(5)).add("three times");
    

    シミュレーション戻りメソッドなしで例外を放出

    doThrow(new RuntimeException()).when(mockedList).clear();
    //following throws RuntimeException:
    mockedList.clear();
    

    メソッド呼び出し順序の検証

     // A. Single mock whose methods must be invoked in a particular order
     List singleMock = mock(List.class);
     //using a single mock
     singleMock.add("was added first");
     singleMock.add("was added second");
     //create an inOrder verifier for a single mock
     InOrder inOrder = inOrder(singleMock);
     //following will make sure that add is first called with "was added first, then with "was added second"
     inOrder.verify(singleMock).add("was added first");
     inOrder.verify(singleMock).add("was added second");
    
     // B. Multiple mocks that must be used in a particular order
     List firstMock = mock(List.class);
     List secondMock = mock(List.class);
     //using mocks
     firstMock.add("was called first");
     secondMock.add("was called second");
     //create inOrder object passing any mocks that need to be verified in order
     InOrder inOrder = inOrder(firstMock, secondMock);
     //following will make sure that firstMock was called before secondMock
     inOrder.verify(firstMock).add("was called first");
     inOrder.verify(secondMock).add("was called second");
     // Oh, and A + B can be mixed together at will
    

    メソッドが呼び出されていないかどうかを確認

     //using mocks - only mockOne is interacted
     mockOne.add("one");
     //ordinary verification
     verify(mockOne).add("one");
     //verify that method was never called on a mock
     verify(mockOne, never()).add("two");
     //verify that other mocks were not interacted
     verifyZeroInteractions(mockTwo, mockThree);
    

    Mockオブジェクトの迅速な作成

    public class ArticleManagerTest {
       @Mock private ArticleCalculator calculator;
          @Mock private ArticleDatabase database;
          @Mock private UserProvider userProvider;
          @Before
          public void before(){
              MockitoAnnotations.initMocks(this);
          }
    }
    

    カスタムは異なる結果を返します

    when(mock.someMethod("some arg"))
       .thenThrow(new RuntimeException())  //  
       .thenReturn("foo"); //  
    //First call: throws runtime exception:
    mock.someMethod("some arg"); //  
    //Second call: prints "foo"
    System.out.println(mock.someMethod("some arg")); //  
    //Any consecutive call: prints "foo" as well (last stubbing wins).
    System.out.println(mock.someMethod("some arg")); //  n (n> 2), 
    

    戻り結果をブロック

    when(mock.someMethod(anyString())).thenAnswer(new Answer() {
        Object answer(InvocationOnMock invocation) {
            Object[] args = invocation.getArguments();
            Object mock = invocation.getMock();
            return "called with arguments: " + args;
        }
    });
    //the following prints "called with arguments: foo"
    System.out.println(mock.someMethod("foo"));
    

    Mock関数操作


    定義関数操作は、doThrow()、doAnswer()、doNothing()、doReturn()and doCallRealMethod()を使用して実行できます.

    実際のオブジェクトをひそかに呼び出す

    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* methods
    spy.add("one");
    spy.add("two");
    //prints "one" - the first element of a list
    System.out.println(spy.get(0));
    //size() method was stubbed - 100 is printed
    System.out.println(spy.size());
    //optionally, you can verify
    verify(spy).add("one");
       verify(spy).add("two");
    

    デフォルトの戻り値を変更

    Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
    Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
    

    関数のパラメータ値の取得

    ArgumentCaptor argument = ArgumentCaptor.forClass(Person.class);
    verify(mock).doSomething(argument.capture());
    assertEquals("John", argument.getValue().getName());
    

    部分ロック

    //you can create partial mock with spy() method:
    List list = spy(new LinkedList());
    //you can enable partial mock capabilities selectively on mocks:
    Foo mock = mock(Foo.class);
    //Be sure the real implementation is 'safe'.
    //If real implementation throws exceptions or depends on specific state of the object then you're in trouble.
    when(mock.someMethod()).thenCallRealMethod();
    

    ロックをリセット

    List mock = mock(List.class);
    when(mock.size()).thenReturn(10);
    mock.add(1);
    reset(mock);
    //at this point the mock forgot any interactions & stubbing
    

    シーケンス化

    List list = new ArrayList();
    List spy = mock(ArrayList.class, withSettings()
                     .spiedInstance(list)
                     .defaultAnswer(CALLS_REAL_METHODS)
                     .serializable());
    

    チェックタイムアウト

    //passes when someMethod() is called within given time span
    verify(mock, timeout(100)).someMethod();
    //above is an alias to:
    verify(mock, timeout(100).times(1)).someMethod();
    //passes when som`eMethod() is called *exactly* 2 times within given time span
    verify(mock, timeout(100).times(2)).someMethod();
    //passes when someMethod() is called *at least* 2 times within given time span
    verify(mock, timeout(100).atLeast(2)).someMethod();
    //verifies someMethod() within given time span using given verification mode
    //useful only if you have your own custom verification modes.
    verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();
    

    Mock詳細

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