Groovy
spock
jMockit

JavaのstaticメソッドをSpockとjMockitでモック化する

More than 3 years have passed since last update.

テストコードを Groovy と Spock で生産性よく書いていますが、

プロダクトコードは政治的な都合により Java で書いています。

プロダクトコードが Java、テストコードが Groovy だと大体の場合は

Groovy や Spock のお作法で問題なくテストコードをかけますが、

static メソッドだけはうまくいきません。


前提事項の整理

Groovy には metaClass という便利なものがありますが、

Java で実装されたクラスに対しては metaClass を使ってふるまいを変更できません。

また、Spock の Mock は static メソッドには使えません。

一方で、実際の開発ではユーティリティという名の static メソッドが

あふれかえっているため、テストコードを書こうとすると結構苦労します。

(static メソッドの中で DB アクセスとか平気で実行されて…むむむ)


jMockit を使えば…?

Groovy の公式サイトには Java クラスの static メソッドに対しては

jMockit 使えばモック化できるみたいなことを書いています。

http://groovy.codehaus.org/Mocking+Static+Methods+using+Groovy

http://groovy.codehaus.org/Using+JMockit+with+Groovy

mockit.Mockit クラスの redefineMethods メソッドを使うサンプルが紹介されています。

が・・・ Mockit クラスには redefineMethods メソッドが存在しません。

ver 0.999 と ver 1.8 で見てみましたが存在しませんでした。ver 1.8 は Mockit クラス自体いない状態です。


mockit.MockUp クラスを使うと、うまくいきました


サンプルコード①:static メソッドのある、モック化対象クラス


JavaSampleClass.java

package sample;

public class JavaSampleClass {

public static String staticMethod1(String value1, int value2) {

return value1 + staticMethod2(value2);
}

public static int staticMethod2(int value3) {
return value3 * 2;
}
}



サンプルコード②:Spock テストコードで MockUp クラスを使う


SpockSampleSpec.groovy

package sample

import mockit.Mock
import mockit.MockUp
import spock.lang.Specification

class SpockSampleSpec extends Specification {

def "staticMethod1は「第1引数の文字列」と「staticMethod2メソッドに第2引数を渡した結果」を結合した文字列を返す"() {
given:
new MockUp<JavaSampleClass>() {
@Mock
int staticMethod2(int value3) {
return value3
}
}

expect:
JavaSampleClass.staticMethod1("abc", 1) == "abc1"
}
}



補足

jMockit モック化するメソッドの期待値を実装する Expectations や NonStrictExpectations を

Spock で使おうとすると実行時エラーになります。

new Expectations() {{

JavaSampleClass.staticMethod1("abc", 1); result = "abc1";
}};