【JUnit】【Mock】 JMockit ~入門編~

■ 設定手順

[1] JMockit をダウンロードする

 * 下記URLから JMockitjmockit-X.X.zip)を取得する。
   => 下記のサイトからリンク「current release」を押下して取得する
http://jmockit.googlecode.com/svn/trunk/www/gettingStarted.html

[2] ダウンロードしたファイル「jmockit-X.X.zip」を解凍する

 * Windows8の環境下で解凍ソフト「Lhaplus」を使用して解凍したら
   警告やらエラーが出て、正常に解凍されない(★ここではまった★)
   => ファイル「jmockit-X.X.zip」を右クリックし「すべて展開(T)」を選択し
      解凍すればOK!

[3] jar をEclipseに取り込む

 [3-1] 解凍したフォルダ内の以下のJarファイルを 
       対象のプロジェクト内の任意のフォルダ(ここでは「lib」)に格納する
   + jmockit.jar
   + jmockit-coverage.jar

 [3-2] 対象のプロジェクトを右クリックし、[Properties]-[Java Build Path]-[Libraries]で
    「Add JARs」ボタン押下し [3-1]で格納したJarファイルを追加する

[4] jmockit をクラスパスをJUnit本体より先にする

 * jmockitのクラスパスをJUnit本体より先にしなければならないという制約があるため。

 [4-1] 対象のプロジェクトを右クリックし、[Properties]-[Java Build Path]-[Order and Export]を選択
 [4-2] [JUnit4」が「jmockit.jar」「jmockit-coverage.jar」よりも上に表示されている場合
       [JUnit4」を選択し「Bottom」ボタン押下

[5] プログラムを書く

 * 以下のサンプルを参照のこと

[6] テスト実行

 * 後は右クリックし、[Run As]-[JUnit Test]でテスト実行

■ サンプル

Mock対象のクラス「SampleClass.java

public class SampleClass {
   public String getValue() {
      return "Hellow World!";
   }
}

テストクラス「SampleClass01Test.java

import static org.junit.Assert.*;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import org.junit.Test;

public class SampleClassTest {
   @Mocked
   private SampleClass mockSampleClass;

   @Test
   public void testGetValue() throws Exception {
      new NonStrictExpectations() {
         {
            mockSampleClass.getValue();
            result = "Fixed value";
         }
      };
      
      assertEquals("Fixed value", this.mockSampleClass.getValue());
   }
}

■ 出力結果

Windows8環境下で動かない。。。

# Linuxだと動くのに。

トラブルシューティング

実行時に以下の例外で動かない。。。

java.lang.IllegalStateException: Native library for Attach API not available in this JRE
	at mockit.internal.startup.AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(AgentLoader.java:88)
	at mockit.internal.startup.AgentLoader.loadAgent(AgentLoader.java:47)
	at mockit.internal.startup.AgentInitialization.loadAgentFromLocalJarFile(AgentInitialization.java:27)
	at mockit.internal.startup.Startup.initializeIfPossible(Startup.java:252)
	at org.junit.runner.Runner.<clinit>(Runner.java:22)
	at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
	at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
	at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
	at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
	at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.UnsatisfiedLinkError: no attach in java.library.path
	at java.lang.ClassLoader.loadLibrary(Unknown Source)
	at java.lang.Runtime.loadLibrary0(Unknown Source)
	at java.lang.System.loadLibrary(Unknown Source)
	at sun.tools.attach.WindowsVirtualMachine.<clinit>(WindowsVirtualMachine.java:185)
	at mockit.internal.startup.AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(AgentLoader.java:66)
	... 17 more
java.lang.NoClassDefFoundError: org.junit.runner.Runner
	at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:61)
	at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

参考文献

以下が関係?
http://kishkz.hatenablog.jp/entry/2012/11/10/165147

■ 利点

 * 他のMockとの比較して、機能を網羅されている(以下を参照のこと)
https://code.google.com/p/jmockit/wiki/MockingToolkitComparisonMatrix

■ 補足

 * private 定数(private static final)は変更できないらしい