PowerMockでハマったので備忘。
クラス内処理で毎回インスタンスが生成されるようなクラスをテストしたい場合、生成されるインスタンス内の処理をモック化(つまり、テスト用に理想的なIN/OUTを設定)するには、PowerMockを用いる必要があります。
この際、ソースは下記のようになります
※下記の記事のソースにコメントを追記したものです
テスト対象クラス
public class ExampleService {
public Integer count() {
ExampleLogic logic = new ExampleLogic();
//テストに当たって、countExamplesの処理はどうでもいいのでモック化したい
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)
//hiroがハマったポイント、PreparedForTest
@PrepareForTest({ ExampleService.class })
public class ExampleServiceTest {
ExampleService service = new ExampleService();
@Test
public void count() throws Exception {
ExampleLogic logic = mock(ExampleLogic.class);
whenNew(ExampleLogic.class).withNoArguments().thenReturn(logic);
when(logic.countExamples()).thenReturn(0);
assertThat(service.count(), equalTo(0));
}
}
hiroがハマったのはPreparedForTestの中身にどのクラスを書くか、でした。
正解
//テスト対象のクラスを書くのが正解
@PrepareForTest({ ExampleService.class })
不正解
//モック化されるクラスを書くと不正解
@PrepareForTest({ ExamleLogic.class })
不正解の方を書くと、うまくモック化されず実際の処理が行われてしまいます。
今後気を付けていきます!