Tagbangers Blog

JMockitを使ってprivateメソッドをモックにしてみた話

JMockitは、ユニットテストで使用するいろいろなことができるライブラリです。

今日はその中からprivateメソッドのモックの仕方について紹介します。

ユニットテストを書いていて、privateメソッド関係ないから無視したいな〜という時に使えます。


まず、MVN REPOSITORYからお好きなバージョンを選択し、pom.xmlに追記します。

<dependency>
    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.30</version>
</dependency>


次にテスト対象クラス。JmockitSample.java

package com.example;

public class JmockitSample {
    public static void main(String[] args){
        System.out.println(new JmockitSample().methodPublic());
        System.out.println(methodPublicStatic());
        System.out.println(new JmockitSample().callPrivateMethod());
        System.out.println(callPrivateStaticMethod());
    }

    public String methodPublic() {
        return "methodPublic";
    }

    public static String methodPublicStatic() {
        return "methodPublicStatic";
    }

    public String callPrivateMethod(){
        return new JmockitSample().methodPrivate();
    }

    private String methodPrivate() {
        return "methodPrivate";
    }

    public String callPrivateMethodTwoArgs(){
        return new JmockitSample().methodPrivate("TEST", 1);
    }

    private String methodPrivate(String value, Integer no) {
        return value + no;
    }

    public static String callPrivateStaticMethod(){
        return JmockitSample.methodPrivateStatic();
    }

    private static String methodPrivateStatic() {
        return "methodPrivateStatic";
    }

    public void callPrivateVoidMethod(){
        new JmockitSample().voidMethodPrivate(1);
    }

    private void voidMethodPrivate(int no) {}
}


次にテストクラスです。JmockitSampleTest.java

package com.example;

import mockit.Mock;
import mockit.MockUp;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;

import static org.junit.Assert.assertEquals;
import static org.mockito.MockitoAnnotations.initMocks;

public class JmockitSampleTest {

    @InjectMocks
    private JmockitSample jmockitSample;

    private int sum = 0;

    @Before
    public void setup() {
        initMocks(this);
    }

    @Test
    public void mockTest(){

        new MockUp<JmockitSample>() {
            @Mock
            private String methodPrivate() {
            return "mocked methodPrivate";
        }

        @Mock
        private String methodPrivate(String value, Integer no) {
            return "mocked methodPrivate two args";
        }

        @Mock
        private String methodPrivateStatic() {
            return "mocked methodPrivateStatic";
        }

        @Mock
        private void voidMethodPrivate(int no) {
            sum += 5;
        }
    };

    assertEquals(new JmockitSample().methodPublic(), "methodPublic");
    assertEquals(JmockitSample.methodPublicStatic(), "methodPublicStatic");
    assertEquals(new JmockitSample().callPrivateMethod(), "mocked methodPrivate");
    assertEquals(new JmockitSample().callPrivateMethodTwoArgs(), "mocked methodPrivate two args");
    assertEquals(JmockitSample.callPrivateStaticMethod(), "mocked methodPrivateStatic");

    new JmockitSample().callPrivateVoidMethod();
    assertEquals(5, sum);
  }
}


JmockitSampleTestを実行するとテストができると思います。

1点注意点!JunitライブラリよりJMockitを先に読み込むようにしてください。(ビルド時にIllegalStatementExceptionが起きるのを防ぐため)