Mockito でモックオブジェクトを初期化する

環境

内容

Mockito の Mock アノテーションを使ってモックを使ったテストを書きたい場合、 モックオブジェクトを初期化する処理を入れる必要がある。方法は調べた限り3つある様子。

Mock (Mockito 2.8.9 API)

MockitoAnnotations.initMocks(this) method has to be called to initialize annotated objects. In above example, initMocks() is called in @Before (JUnit4) method of test's base class. For JUnit3 initMocks() can go to setup() method of a base class. Instead you can also put initMocks() in your JUnit runner (@RunWith) or use the built-in MockitoJUnitRunner.

方法1 Before アノテーションを使って initMocks() を呼ぶ。

下記は javadoc から。(テストケースで継承するという実装の是非はここでは問わない。) このコードでは Before アノテーションで各テストケース毎に初期化する MockitoAnnotations.initMocks(this) を呼び出す基底クラスを作り、継承先でモックオブジェクトを定義している。

   public class ArticleManagerTest extends SampleBaseTestCase {

       @Mock private ArticleCalculator calculator;
       @Mock(name = "database") private ArticleDatabase dbMock;
       @Mock(answer = RETURNS_MOCKS) private UserProvider userProvider;
       @Mock(extraInterfaces = {Queue.class, Observer.class}) private  articleMonitor;

       private ArticleManager manager;

       @Before public void setup() {
           manager = new ArticleManager(userProvider, database, calculator, articleMonitor);
       }
   }

   public class SampleBaseTestCase {

       @Before public void initMocks() {
           MockitoAnnotations.initMocks(this);
       }
   }
 

方法2 RunWith アノテーションに MockeitoJUnitRunner を指定する。

下記コードは javadoc から。

MockitoJUnitRunner.class で指定するとデフォルトでは MockitoJUnitRunner.Strict が使われるものと同等となる。javadoc を見る限りだと 下記コードのように StrictStubs を使うことが推奨されている。

ちなみに MockitoJUnitRunner を使う場合は Test アノテーションがないと動かない。( JUnit 側の Runner のバリデーションの問題)

 @RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class ExampleTest {

     @Mock
     private List list;

     @Test
     public void shouldDoSomething() {
         list.add(100);
     }
 }
 

方法3 JUnit の MethodRule を実装した MockitoRule を使う

SpringRunner や Theories などの Runner を使いたいため MokcitJUnitRunner が指定できない場合などは Mockito のほうを Rule で動かしてやると同じような挙動をする。使用する際には MocketoJUnit から取得するらしい。

 public class ExampleTest {

     //Creating new rule with recommended Strictness setting
     @Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);

     @Mock
     private List list;

     @Test
     public void shouldDoSomething() {
         list.add(100);
     }
 }
 

ドキュメント