Mockito+PowerMockで不可視メソッドをspy
目的
privateメソッドやパッケージ違いの親クラスのprotectedメソッドのようにテストコードから不可視なメソッドにspyを適用したい。
方法
PowerMockito.whenを使う。
Target target = PowerMockito.spy(new Target()); PowerMockito.when(target, "invisibleMethod", "hoge").thenReturn("mock-string");
(参考:Mockitoのspy)
Target target = Mockito.spy(new Target()); Mockito.when(target.method("hoge")).thenReturn("mock-string");
検証
いろんな不可視パターンで試してみる
ソースコード
テスト対象クラス
package kurukuruz.test.mock; import kurukuruz.test.mock.base.Parent; public class Target extends Parent { public String executeOwnMethod(){ return "own method return: " + private1(); } private String private1() { return "own"; } public String executeParent1() { return "method1 return: " + method1(); } public String executeParent2() { return "method2 return: " + method2(); } public String executeParent3() { return "method3 return: " + method3(); } public String executeParent4(String hoge) { return "method4 return: " + method4(hoge); } public String executeParent5(Dao dao) throws Exception { return "method5 return: " + method5(dao); } }
親クラス
package kurukuruz.test.mock.base; import lombok.Getter; import lombok.Setter; public class Parent { /** publicメソッド */ public String method1() { return "method1"; } /** protectedメソッド */ protected String method2() { return "method2"; } /** protected finalメソッド */ protected final String method3() { return "method3"; } /** 引数あり(文字列) */ protected final String method4(String hoge) { return hoge; } /** 引数が任意のオブジェクト */ protected final String method5(Dao dao) throws Exception { if(dao.getName() == null) { throw new Exception("name is null!"); } return dao.getName(); } @Setter @Getter public static class Dao { private String name; } }
テストコード
package kurukuruz.test.mock; import kurukuruz.test.mock.base.Parent.Dao; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.runners.Enclosed; 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(Enclosed.class) public class TargetTest { public static class そのまま実行 { @BeforeClass public static void setupBeforeClass() { System.out.println("---そのまま実行---"); } @Test public void テスト0() throws Exception{ Target t = new Target(); System.out.println(t.executeOwnMethod()); } @Test public void テスト1() throws Exception{ Target t = new Target(); System.out.println(t.executeParent1()); } @Test public void テスト2() throws Exception{ Target t = new Target(); System.out.println(t.executeParent2()); } @Test public void テスト3() throws Exception{ Target t = new Target(); System.out.println(t.executeParent3()); } @Test public void テスト4() throws Exception{ Target t = new Target(); System.out.println(t.executeParent4("hoge")); } @Test public void テスト5() throws Exception{ Target t = new Target(); Dao param1 = new Dao(); param1.setName("foo"); System.out.println(t.executeParent5(param1)); } } @RunWith(PowerMockRunner.class) @PrepareForTest({Target.class}) public static class モック実行 { @BeforeClass public static void setupBeforeClass() { System.out.println("---モック実行---"); } @Test public void テスト0() throws Exception{ Target t2 = PowerMockito.spy(new Target()); PowerMockito.when(t2, "private1").thenReturn("mock0"); System.out.println(t2.executeOwnMethod()); } @Test public void テスト1() throws Exception { Target t2 = PowerMockito.spy(new Target()); PowerMockito.when(t2, "method1").thenReturn("mock1"); System.out.println(t2.executeParent1()); } @Test public void テスト2() throws Exception { Target t2 = PowerMockito.spy(new Target()); PowerMockito.when(t2, "method2").thenReturn("mock2"); System.out.println(t2.executeParent2()); } @Test public void テスト3() throws Exception { Target t2 = PowerMockito.spy(new Target()); PowerMockito.when(t2, "method3").thenReturn("mock3"); System.out.println(t2.executeParent3()); } @Test public void テスト4() throws Exception { Target t2 = PowerMockito.spy(new Target()); PowerMockito.when(t2, "method4", "hoge").thenReturn("mock4"); System.out.println(t2.executeParent4("hoge")); System.out.println(t2.executeParent4("foo")); } @Test public void テスト5() throws Exception { Target t2 = PowerMockito.spy(new Target()); Dao dao = new Dao(); dao.setName("bar"); PowerMockito.when(t2, "method5", dao).thenReturn("mock5"); System.out.println(t2.executeParent5(dao)); } } }
実行結果
---そのまま実行--- own method return own method1 return method1 method2 return method2 method3 return method3 method4 return hoge method5 return foo ---モック実行--- method4 return mock4 method4 return foo method1 return mock1 own method return mock0 method2 return mock2 method3 return mock3 method5 return mock5