/home/by-natures/dev*

データ界隈で働くエンジニアとしての技術的なメモと、たまに普通の日記。

JMockit で File クラスをモックする

業務では JMockit(公式ページ)を利用してテストを書いているのですが、ファイル入出力を利用したクラスの単体テストが書きたいと思い、JMockit で File クラスをモックできないかを調べました。

JMockit とは

Java の単体テスト向けフレームワークの1つです。

似た名前のテストフレームワークに mockito というものがあります。同じようなことができるのですが、記述方法がかなり違います。また、Spring では mockito に依存しているプロジェクトがあるため、なんとなくで使っていると、JMockit を使っているつもりが、mockito だった…ということが起こりかねません。(JMockit のパッケージ名が mockit なのも混乱の元ではないでしょうか。。)

会話では JMockit は(ジェーモックイット)、mockito は(モキート)と言えば伝わりやすいかと思います。

違いがまとまった Qiita のページがありました:

qiita.com

File クラスをモックする

ファイル入出力の動作確認であれば、一時ファイルを使ってテストが終わったら破棄するようにしてもよいのですが、ファイルサイズによって分岐する処理をテストしたかったため、File クラスをモックできないかと調べました。

GoogleGroups で、JMockit での File クラスのモックについて議論がされています。

https://groups.google.com/forum/#%21topic/jmockit-users/ocPNN4RxlXk

その中の一つに次の方法があります:

  @Test
  public void testSomeMethod() throws Exception {
    // prepare
    new MockUp<File>() {
      @Mock public long length() { return 100; }  // 100byte
      @Mock boolean renameTo(File file) { return true; }
      @Mock boolean exists() { return true; }
    };

    // execute
    // Do execute some code

    // verify
    new Verifications() {{
      ...
    }};
  }

これを実行すると、File クラス全てがモックアップされます。動作としては分かりやすいのですが、File クラスのように様々なところで使われているクラスだと意図しないオブジェクトまでモックにしてしまい、NoClassDefFoundErrorClassNotFoundException が頻発するので使い方には注意が必要です。

mockito だと特定のオブジェクトだけモックにすることが簡単なようなのですが、まだ確認できていません。