2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめに

voidメソッドに対してmockを設定するにはどうすればいいのだろうか。
when return出来ないし〜と悩んだ際の調べた内容について記載します。

こんな人に読んでほしい

voidメソッドのJunitいまいち書き方がわからん方。

do〜の種類

結論、do〜のmockitoを使ってvoidメソッドのmockを設定することができます。

以下今回テストしたいvoidメソッド

public class MyList extends AbstractList<String> {
 
    @Override
    public void add(int index, String element) {
        // ~~~
    }
}

1.doNothing

- 文字通り何もしてほしくない時に使います。
- doNothing()は、voidメソッドに対するMockitoのデフォルトの動作になります。

基本的な書き方は以下です。

doNothing().when(sampleService).methodA(any());
@Test
public void whenAddCalledVerified() {
    MyList myList = mock(MyList.class);
    //指定してもしなくても動く
    doNothing().when(myList).add(isA(Integer.class), isA(String.class));
    
    // 呼出
    myList.add(0, "");
 
    // 検証
    verify(myList, times(1)).add(0, "");
}

voidメソッドについて何もしない(デフォルトの動作)をしてほしい時、上記のように設定できます。
ただ、最初に記載しているように、doNothing() は、voidメソッドに対するMockitoのデフォルトの動作ですので、
doNothing()を指定しなくてもデフォルトで動きます。

2. doThrow

- エラーをvoidメソッドの中で投げて返してほしい時に使います。

基本的な書き方は以下です。

doThrow(exception).when(sampleService).methodA(any());
@Test(expected = Exception.class)
public void givenNull_AddThrows() {
    MyList myList = mock(MyList.class);
    doThrow(new RuntimeException()).when(myList).add(isA(Integer.class),isA(String.class));
 
    // 呼出
    Try{
        myList.add(0, null);
        fail();
    } catch() {
        // 検証
    }   
}

doThrow を使って、呼び出した時に、RuntimeException()を引き起こすような挙動は上記のように設定できます。

3.doAnswer

- voidメソッドの中でやってほしいことがある場合に使います。
- 例えば、引数で渡したものをvoidメソッドの中で更新したい時なんかに使います。
@Test
void whenAddCalledAnswered() {
    MyList myList = mock(MyList.class);
    doAnswer(invocation -> {
        // 第1引数何かな?を取得
        Object arg0 = invocation.getArgument(0);
        
        // 第一引数を+1 するように設定
        arg++;

        return null;
    }).when(myList).add(any(Integer.clas), any(String.class));
    int beforeNum = 5;
    myList.add(beforeNum, "answer me");
    // 検証
    ~~~
}

上記の書き方では、引数を invocation.getArgument() で取得して、そいつを更新させるような設定をしてみました。
なかなか使う機会は少ないかもしれませんが。

1回目と2回目の挙動を変えたい時

thenReturn() は、1回目と2回目返すもの変えたい時以下のようにすれば、返却値を変更できまが、

when(sampleService.methodA(any())).thenReturn("1回目").thenReturn("2回目");

do〜系 も呼ばれる度に挙動を変えることができます。
今回の例で言うと、1回目、2回目は何もせず、3回目で例外を投げたい時、下記のようにかけます。

doNothing().doNothing().doThrow(new RuntimeException()).when(sampleService).methodA(any());

参考

https://qiita.com/fumu238/items/64c910bc36b051c6b976
https://www.baeldung.com/mockito-void-methods

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?