mockito雑多なサンプル

2018年1月26日

その他のサンプル1

import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;

import org.junit.*;

public class TestOne {

  /** ログインを処理するインターフェース */
  public interface Login {
    boolean login(String user, String password);
  }

  Login mock;

  @Before
  public void setup() {
    mock = mock(Login.class);
  }

  @Test
  public void testOne() {
    // 何も設定しない場合はfalseやnullが返る。
    assertFalse(mock.login("guest", "pass"));
  } 

  @Test
  public void testTwo() {

    // "guest", "pass"というパラメータで呼び出されたときにtrueを返すように設定する。
    when(mock.login("guest", "pass")).thenReturn(true);

    // 実際に呼び出してtrueが返されることを確認
    assertTrue(mock.login("guest", "pass"));

    // このパラメータで一度だけ呼び出されたことを確認
    verify(mock).login("guest", "pass");    

    // 上は、以下の省略形である。
    verify(mock, times(1)).login("guest", "pass");    

    // 「少なくとも一度」という指定も可能
    verify(mock, atLeast(1)).login("guest", "pass");   

    // 以下は失敗する
    //verify(mock, times(2)).login("guest", "pass");   
    //verify(mock, atLeast(2)).login("guest", "pass");   
  }

  @Test
  public void testThree() {

    // パスワードが空のときは例外にするように設定
    when(mock.login("guest", "")).thenThrow(new RuntimeException());

    // 呼び出し
    try {
      mock.login("guest", "");
      fail();
    } catch (RuntimeException ex) {      
    }

    // このパラメータで呼び出されたことを確認
    verify(mock).login("guest", "");    

    // 以下は失敗する
    //verify(mock).login("guest", "guest");    
  }

  @Test
  public void testFour() {
    // 複数の引数パターンを使うことが可能
    when(mock.login("guest", "pass")).thenReturn(true);
    when(mock.login("guest", "1234")).thenReturn(true);    
    assertTrue(mock.login("guest", "pass"));    
    assertTrue(mock.login("guest", "1234"));    

    // 以前と同じ引数パターンをオーバーライド
    when(mock.login("guest", "pass")).thenReturn(false);    
    assertFalse(mock.login("guest", "pass")); 

    // 呼び出された回数
    verify(mock, times(2)).login("guest", "pass");    
    verify(mock, times(1)).login("guest", "1234");    
  }

  @Test
  public void testFive() {

    // 引数はなんでもいいというときには「anyなんとか」を使う。
    // 以下はパスワードはなんでもいい場合で、anyObject()
    // また、この場合はなぜか"guest"ではだめで、eq("guest")としなければならない。
    when(mock.login(eq("guest"), (String)anyObject())).thenReturn(true);

    // いずれの場合もOK    
    assertTrue(mock.login("guest", "pass"));    
    assertTrue(mock.login("guest", "1234")); 

    // いずれも成功する
    verify(mock).login("guest", "pass"); 
    verify(mock).login("guest", "1234"); 
    verify(mock, times(2)).login(eq("guest"), (String)anyObject());
  }
}

その他のサンプル2

package com.cm55.mockitoTest.one;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.junit.*;
import org.mockito.*;

public class TestTwo {

  public interface IntegerBox {
    boolean add(int value);
    void clear();
  }

  // MockitoAnnotaions.initMocks()を呼び出すと、
  // @Mockアノテーションのついた宣言にモックが入れられる。
  @Mock IntegerBox mock;

  @Before
  public void setup() {
    // すべての@Mockにモックを代入
    MockitoAnnotations.initMocks(this);    
  }

  @Test
  public void testOne() {
    // 何も設定しない場合はfalseやnullや0が返る。
    assertFalse(mock.add(5));
  } 

  @Test
  public void testTwo() {

    // 一度目、二度目、三度目に引数(10)で呼び出すと
    // それぞれ、true, false, 例外となる指定
    when(mock.add(10))
      .thenReturn(true)
      .thenReturn(false)
      .thenThrow(new RuntimeException());

    assertTrue(mock.add(10));  // 1度目
    assertFalse(mock.add(20)); // これは20での呼び出しで無関係
    assertFalse(mock.add(10)); // 2度目
    try {
      mock.add(10);            // 3度目
      fail();
    } catch (RuntimeException ex) {      
    }

    verify(mock, times(3)).add(10);    
    verify(mock).add(20);
  }

  @Test
  public void testThree() {

    // 返り値の無いメソッド呼び出しで例外を発生させたい場合は、
    // 以下の特別な指定が必要。
    // 返り値が無いのでwhen(mock.clear()).thenThrow(...)とは書けない。
    doThrow(new IllegalStateException()).when(mock).clear();

    try {
      mock.clear();
      fail();
    } catch (IllegalStateException ex) {}
  }
}

その他のサンプル3

package com.cm55.mockitoTest.one;

import org.junit.*;
import static org.mockito.Mockito.*;

public class TestThree {

  public interface IntegerBox {
    boolean add(int value);
    void clear();
  }

  /** 作成されたが、何のメソッドも呼ばれていないことを確認する */
  @Test
  public void testOne() {    
    IntegerBox one = mock(IntegerBox.class);
    IntegerBox two = mock(IntegerBox.class);
    two.add(1); // twoのメソッドを呼び出した

    verifyZeroInteractions(one);    // oneは何のメソッドも呼び出されていない。
    // verifyZeroInteractions(two); // これは失敗する。twoのメソッドは呼び出されたから
  }

  /** verifyされていないinteraction(メソッド呼び出し)が存在しないことの確認 */
  @Test
  public void testTwo() {    
    IntegerBox one = mock(IntegerBox.class);    

    // 二種類のメソッド呼び出しを行い、それを確認する。
    one.add(1);
    one.add(2);
    verify(one).add(1);

    // verifyNoMoreInteractions(one); これは失敗するone.add(2)をverifyしていない。

    // one.add(2)をverifyする。
    verify(one).add(2);

    verifyNoMoreInteractions(one); // verifyしていない呼び出しは存在しない。
  }
}