A little note from 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
    }
}
For example, when creating a mock of ʻApiServiceas shown above and calling therequest ()` method.
I think there are situations where you want to set a value in the constructor.
At this time, you can pass the argument to the constructor while creating a mock object by using MockSetting # useConstructor as the second argument ofmock ().
    @Test
    public void test() {
        ApiService apiService = mock(ApiService.class, withSettings().useConstructor("http://localhost", 100));
        when(apiService.request()).thenCallRealMethod();
        apiService.request(); // -> http://localhost
    }
If you try to put logging in the constructor, the log will also be output, so you can see that the processing in the constructor is also being executed.
I basically want to call the original method when testing, but I want to mock only some of the methods. .. .. I think there is something like that.
ApiService apiService = mock(ApiService.class,
 withSettings().defaultAnswer(CALLS_REAL_METHODS));
This defaults to callRealMethod by passing CALLS_REAL_METHODS to MockSetting # defaultAnswer.
However, there is one caveat, you need to be careful when using when () in a method that is callRealMethod.
    @Test
    public void test() {
        ApiService apiService = mock(ApiService.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
        when(apiService.request()).thenReturn("hogehoge"); // -> throw IllegalStateException
    }
The above code seems to work normally, but the method is called at the time of when (apiService.request ()).
It seems better to use doReturn to avoid this.
    @Test
    public void test() {
        ApiService apiService = mock(ApiService.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
        doReturn("hogehoge").when(apiService).request();
        apiService.request(); // -> hogehoge
    }
You can use doReturn to set the mock without calling callRealMethod.
Recommended Posts