JMockitでprivateメソッドを呼ぶ方法

出向先でJunitを使う機会があったので、コンパイルエラーしやすい箇所をここで備忘録として書き込むようにしておく。

 

package test;


public class Test1  {

 

       String runSample() { String runSample() {
              // 未実装
              return null;
       }
  private int numberReturn(int a,int b) {
    int result;
    result = a + b;
    return result;
  } void main() {
    int sum = 0;
    sum = numberReturn(2,3);
  }

}

 

Test1.javaこのソースにおけるnumberReturnメソッドをモック化して一度呼び出したい場合

package test;
import static org.hamcrest.CoreMatchers.*;

import static org.junit.Assert.*;
import org.junit.jupiter.api.Test;
import mockit.Mock;

import mockit.MockUp;
class Test1Test {

  @Test

  public void test_numberReturn() {

    new MockUp<Test1>() {

    @Mock()

    public int numberReturn(int a,int b) {

       return a+b;

      }

    };
    Test1 s = new Test1();

    int a = s.numberReturn(3,4);

    assertThat(a, is("1"));

    }

}

 

 上記のように記載すると37行目のs.numberReturn(3,4);でメソッドが不可視ですというエラーが出力される。

この場合privateメソッドはモックとして呼ばれないので、対象となるprivateメソッドをgetDeclaredMethodでインスタンス化してからsetAccessibleでアクセス出来るように設定させる。

その後はインスタンス化したprivateメソッドをinvokeで呼び出すようにする。

こうすることでprivateメソッドをモックとして呼び出すことに成功できる。

 

package test;
import static org.hamcrest.CoreMatchers.*;

import static org.junit.Assert.*;
import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;

class Test1Test {
@Test

 public void test_numberReturn() throws     

 NoSuchMethodException,

 IllegalAccessException,

 InvocationTargetException    

 {

  Test1 s = new Test1();

  Method method  = Test1.class.getDeclaredMethod

("numberReturn", int.class, int.class);

  method.setAccessible(true);

   int a = (int)method.invoke(s,3,4);

  assertThat(a, is("1")); 

 }

}

 

追記:このgetDeclaredMethodメソッドはアクセス権限が制限されているメソッドをアクセスする為に使う。

似たようなメソッドとしてはgetDeclaredConstructorメソッドでこちらはprivate修飾子が付いたコンストラクタをインスタンスとして生成するのに使われる。