Mockitoを利用したテスト時に、privateメソッド内で@Autowierdされたprivateフィールドが持つメソッドをモック化した場合のメモになります。
事前準備
今回のテスト用に以下のコードを作成します。
- Sampleクラス:@Autowierdしたprivateフィールド(Personクラス)を持ち、privateメソッド(foo())でPerson.getName()の結果を返す
- Personクラス:privateフィールド及びそのゲッターを持つ
// Person.java @Getter public class Person { private String name = "foo"; }
// Sample.java public class Sample { @Autowired private Person person; private String foo() { String name = this.person.getName(); return name; } }
テストコードの作成
以下が作成したテストコードとなります。
// SampleTest.java public class SampleTest { private Sample sample = new Sample(); private Person person; @Before public void setup() { MockitoAnnotations.openMocks(this); this.initPerson(); } @After public void tearDown() throws Exception { } @Test public void testFoo() { when(this.person.getName()).thenReturn("bar"); String result = null; try { result = Whitebox.invokeMethod(this.sample, "foo"); } catch (Exception e) { e.printStackTrace(); fail(); } MatcherAssert.assertThat(result, CoreMatchers.is("bar")); } private void initPerson() { Whitebox.setInternalState(this.sample, "person", Mockito.mock(Person.class)); Field field = null; try { field = Sample.class.getDeclaredField("person"); field.setAccessible(true); this.person = (Person) field.get(this.sample); } catch (Exception e) { e.printStackTrace(); fail(); } } }
今回はPowermockのWhiteBoxというユーティリティクラスを使用し、インスタンス化したテスト対象クラスのprivateフィールドをモッククラスとして上書きする方法を取りました。
そのフィールドインスタンスをリフレクションを利用しアクセスすることで、カプセル化された箇所のテストも容易にできます。