Javaでprivateメソッドをmockに置き換える方法

探していたら、mockitoでは実装してない旨のページを見つけた。

github.com

powermockでできるからそっち使ってねって書いてある(ように読める)…○r2”

社内のMさんとOさんに助けを求めたら教えてもらえたのだが、 どうやら、jmockitなるものを使えば、簡単にstaticだろうがfinalだろうがprivateだろうがmockに置き換えられる模様。 ↓教えてもらったサイト↓ qiita.com

やり方を具体例で教えてもらったが、確かに簡単かつ意図したとおりにできた!

ので、今後お世話になりそうなのでメモしておく。

以下、サンプルコード

package test.jmockit;

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

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

    public static String methodPublicStatic() {
        return "methodPublicStatic";
    }
    
    public String callPraivateMethod(){
        return new JmockitSample().methodPrivate();
    }
    
    private String methodPrivate() {
        return "methodPrivate";
    }

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

実行結果

methodPublic
methodPublicStatic
methodPrivate
methodPrivateStatic

テストコード内で4つのメソッドを前もmockに置き換えて、 Mocked{メソッド名}に変更してみる

package test.jmockit;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import mockit.Mock;
import mockit.MockUp;

import org.junit.Test;

public class JmockitSampleTest {

    @Test
    public void mockTest(){

        new MockUp<JmockitSample>() {

            @Mock
            public String methodPublic() {
                return "mocked methodPublic";
            }

            @Mock
            public String methodPublicStatic() {
                return "mocked methodPublicStatic";
            }

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

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

        System.out.println(new JmockitSample().methodPublic()      );
        System.out.println(JmockitSample.methodPublicStatic()      );
        System.out.println(new JmockitSample().callPraivateMethod());
        System.out.println(JmockitSample.callPrivateStaticMethod() );
        
        assertThat(new JmockitSample().methodPublic(), is("mocked methodPublic"));
        assertThat(JmockitSample.methodPublicStatic(), is("mocked methodPublicStatic"));
        assertThat(new JmockitSample().callPraivateMethod(), is("mocked methodPrivate"));
        assertThat(JmockitSample.callPrivateStaticMethod(), is("mocked methodPrivateStatic"));

    }
}

結果

mocked methodPublic
mocked methodPublicStatic
mocked methodPrivate
mocked methodPrivateStatic

注意点

クラスパスがjunitよりも先に来てないとうまく動かないので、その点だけ注意して下さい。 Eclipseだとこんな感じにすればOK f:id:kogayushi:20150607105459p:plain

gradleならこんな感じ

apply plugin: 'java'
apply plugin: 'eclipse'

sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

configurations {
    jmockit_agent
}

repositories {
    mavenCentral()
}

dependencies {
    jmockit_agent 'com.googlecode.jmockit:jmockit:1.7'
    testCompile 'com.googlecode.jmockit:jmockit:1.7'
    testCompile 'junit:junit:4.11'
    
}

test {
    jvmArgs "-javaagent:${configurations.jmockit_agent.asPath}"
}

ちなみにNetBeansの場合は、gradle使ってる場合はgradleに完全にコンパイル任せてるのでbulid.gradleの設定さえしておけば、うまく動きます。

参考にしたサイトその1 knjname.hateblo.jp

参考にしたサイトその2 gist.github.com