LoginSignup
3
2

More than 3 years have passed since last update.

[Java] Mockitoでコンストラクタに引数を渡す/メソッドのデフォルト呼び出しをcallRealMethodにする

Posted at

Mockitoのちょっとしたメモ

コンストラクタに引数を渡す


package jp.jig.product.live.server.common.service;

import org.junit.Test;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ApiServiceTest {

    public static class ApiService {

        private final String endpoint;
        private final int timeout;

        public ApiService(String endpoint, int timeout) {
            this.endpoint = endpoint;
            this.timeout = timeout;
        }

        public String request() {
            if (endpoint == null) {
                throw new IllegalStateException("endpoint is null");
            }

            return endpoint;
        }

        public boolean validTimeout() {
            return timeout > 0;
        }
    }

    @Test
    public void test() {

        ApiService apiService = mock(ApiService.class);
        when(apiService.request()).thenCallRealMethod();
        apiService.request(); // -> throw IllegalStateException
    }

}

例えば上記のような ApiService のmockを作って、 request() メソッドを callRealMethod する場合などで
コンストラクタで値を設定したいといった場面があると思います。

このとき mock() の第2引数に MockSetting#useConstructor を使うことでmockオブジェクトを作りつつ、コンストラクタに引数を渡すことができます


    @Test
    public void test() {
        ApiService apiService = mock(ApiService.class, withSettings().useConstructor("http://localhost", 100));
        when(apiService.request()).thenCallRealMethod();
        apiService.request(); // -> http://localhost
    }

コンストラクタにロギングを仕込んでみると、ログも出力されるので、コンストラクタ内の処理も実行されていることがわかります。

デフォルト呼び出しをcallRealMethodにする

テストの際に基本的には本来のメソッドを呼び出したいが、一部のメソッドだけモックしたい。。。といったことがあると思います。

ApiService apiService = mock(ApiService.class,
 withSettings().defaultAnswer(CALLS_REAL_METHODS));

こちらは MockSetting#defaultAnswerCALLS_REAL_METHODS を渡すことで、デフォルトでcallRealMethodになります。

ただし注意点が一つあり、callRealMethodになっているメソッドで when() を使うときは注意が必要になります

    @Test
    public void test() {
        ApiService apiService = mock(ApiService.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
        when(apiService.request()).thenReturn("hogehoge"); // -> throw IllegalStateException
    }

上記コードは一見普通に動きそうですが、 when(apiService.request()) の時点でメソッドが呼び出されてしまいます。
これを回避するためには doReturn を使うのがいいらしいです。


    @Test
    public void test() {
        ApiService apiService = mock(ApiService.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
        doReturn("hogehoge").when(apiService).request();

        apiService.request(); // -> hogehoge
    }

doReturnを使うことで callRealMethod を呼び出さずにmockを設定することができます。

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