Mockito+PowerMockでStringのmockを作る
文字列のハッシュ衝突時のテストケースを書くことになりましたが、いつも使っているMockitoはfinal classのmockを作ることができません。
調べてみたところ、PowerMockというモジュールを使うことによって、MockitoのAPIを用いてfinal classのmockを作ることができることが分かり、試してみました。
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import static org.powermock.api.mockito.PowerMockito.*; @RunWith(PowerMockRunner.class) @PrepareForTest(String.class) public class HashCollisionTest { @Test public void testHashCodeEquivalent(){ String foo = "foo"; String bar = "bar"; assertThat(foo.hashCode(), is(not(bar.hashCode()))); bar = spy(bar); when(bar.hashCode()).thenReturn(foo.hashCode()); assertThat(bar, is("bar")); assertThat(foo.hashCode(), is(bar.hashCode())); } }
Mockitoのみを用いた場合と異なるのは以下の3点です。
- static importの変更
- 「org.mockito.Mockito.*」から「org.powermock.api.mockito.PowerMockito.*」に
- @RunWith(PowerMockRunner.class)を追加
- @PrepareForTest([mockの対象となるclass])を追加
PowerMockは既存のmockモジュールを拡張するモジュールで、EasyMockとMockitoに対応しています。final classのmockを作成する為に別のmockモジュールを導入しても良いですが、既にEasyMockやMockitoを使ってテストコードを書いているのであれば、PowerMockを導入してみることをお勧めします。