はじめに
Javaのユニットテストで Mockito + PowerMock でモックする時に、よく使いそうなものをできる限り簡潔にまとめてみます。(随時追記していく予定です)
目次
MockitoとPowerMockを導入する
Gradleの場合、build.gradleに以下の依存関係を追加します。
dependencies {
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-core:2.28.+"
testImplementation 'org.powermock:powermock-module-junit4:2.0.2'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.2'
}
staticメソッドをモック化する
以下のメソッドをテストする場合にメソッドから呼び出しているstaticメソッド「ExampleDBA.findAll()」をモック化してみます。
import java.util.List;
public class ExampleLogic {
public Integer countExamples() {
List<ExampleDTO> list = ExampleDBA.findAll();
return list.size();
}
}
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.powermock.api.mockito.PowerMockito.when;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class) //(1)
@PrepareForTest({ ExampleDBA.class }) //(2)
public class ExampleLogicTest {
ExampleLogic logic = new ExampleLogic();
@Before
public void setUp() throws Exception {
PowerMockito.mockStatic(ExampleDBA.class); //(3)
}
@Test
public void countExamples() {
List<ExampleDTO> result = Arrays.asList(new ExampleDTO());
when(ExampleDBA.findAll()).thenReturn(result); //(4)
assertThat(logic.countExamples(), equalTo(1));
}
}
(1) PowerMockを使う場合に必要なおまじないです。
(2) モック化するstaticメソッドを持つクラスを指定します。
(3) モック化するstaticメソッドを持つクラスを指定します。
(4) staticメソッドが実行された場合の戻り値を指定します。
newされているインスタンスをモック化する
public class ExampleService {
public Integer count() {
ExampleLogic logic = new ExampleLogic();
return logic.countExamples();
}
}
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class) //(1)
@PrepareForTest({ ExampleService.class }) //(2)
public class ExampleServiceTest {
ExampleService service = new ExampleService(); //(3)
@Test
public void count() throws Exception {
ExampleLogic logic = mock(ExampleLogic.class); //(4)
whenNew(ExampleLogic.class).withNoArguments().thenReturn(logic); //(5)
when(logic.countExamples()).thenReturn(0); //(6)
assertThat(service.count(), equalTo(0));
}
}
(1) PowerMockを使う場合に必要なおまじないです。
(2) テスト対象クラスを指定します。
(3) テスト対象クラスのインスタンスを生成します。
(4) モックオブジェクトを作成します。
(5) newされた時にモックオブジェクトを返すように設定します。
(6) モックオブジェクトのメソッドが呼ばれた際の戻り値を設定します。
(*) モック化対象のオブジェクトをnewする前に(4)〜(6)は実施する必要があります。
例えば、ExampleServiceのコンストラクタでExampleLogicをnewしている場合、
ExampleServiceは(6)の後で(3)する必要があります。
一部のメソッドをモック化する
public class ExampleLogic2 {
private String privateMethod() {
return "abc";
}
public String publicMethod() {
String str = privateMethod();
return str.toUpperCase();
}
}
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class) //(1)
@PrepareForTest(ExampleLogic2.class) //(2)
public class ExampleLogicTest2 {
@Test
public void publicMethod() throws Exception {
ExampleLogic2 logic = spy(new ExampleLogic2()); //(3)
when(logic, "privateMethod").thenReturn("str"); //(4)
assertThat(logic.publicMethod(), equalTo("STR"));
}
}
(1) PowerMockを使う場合に必要なおまじないです。
(2) テスト対象クラスを指定します。
(3) 一部のメソッドをモック化するためテスト対象クラスをnewしてspyを呼び出します。
(4) モック化するメソッド(この例ではprivate)の戻り値を設定します。
Comments
Let's comment your feelings that are more than good