LoginSignup
9
8

More than 1 year has passed since last update.

Mockitoのモックオブジェクトをmock()と@Mockで宣言するときの違い

Last updated at Posted at 2019-02-06

2021.06.02 仕様が変わっていたり、少し理解できたので内容を更新しました。

Mockito で Mockオブジェクトを生成する方法には、mockメソッド (mock()) と Mockアノテーション(@Mock) の2種類があるので簡単な使い分けを考察してみました。

:warning: :1 @Mockアノテーションを使った場合の初期化処理だった、 initMocks() および MockitoJUnitRunner は現行バージョン(mockito-core 3.10.0)の時点で、非推奨になっている。

:warning: :2 MockitoのHP の More info の記載内容、および少し実際に試しただけなので、不正確な内容が含まれている可能性はあります。 また、Spyについても概ね同様の考えた方で良いと思います。

mock() と @Mock の使い分け

@InjectMocks を付けたオブジェクトのフィールドを Mockにする場合に、そのMockは @Mockで作成する。
イメージ的には、@InjectMocks@Mock は一緒に宣言して使う。

@Mockで作成するMockオブジェクトは、利用前に初期化し、利用後は後処理(close)を行う。

Mockオブジェクトの宣言パターン

1. mock(Object.class) メソッドで生成する

Mockオブジェクトの基本の生成方法。
前述した通り、 @InjectMocks オブジェクトのフィールド以外をMockにする場合は、こちらを使った方が、前処理と後処理を書かなくて済む。

public class RetrieveBookDetailsTest {
  private BookDao bookDao = mock(BookDao.class);

  @BeforeEach
  void setUp() {
    when(bookDao.findById(1)).thenReturn(new Book());
    when(bookDao.findById(2)).thenReturn(null);
  }
  // 以下、Testメソッド
  ....

2. @Mock アノテーションで宣言する

@Mock で宣言したMockオブジェクトは、 openMocks()メソッドを使って初期化を行う必要がある。
更にこのメソッドの戻り値がAutoCloseableオブジェクトとなるので、テスト終了時に close()メソッドを実行する。

サンプルコードには、 @InjectMocksオブジェクトを宣言するべきだったが、 openMocks()実行時にMockオブジェクトの生成とInjectMocksオブジェクトのフィールドへのInjectionを行っていると思われる。


    private AutoCloseable closeable;

    @Mock
    private Network network;

    @BeforeEach
    void setUp() {
        closeable = MockitoAnnotations.openMocks(this);
    }

    @AfterEach
    void tearDown() throws Exception {
        closeable.close();
    }

これを最初に書いた時よりも、Mockitoって意外とシンプルだなと感じるようにはなった。

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8