25
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

テストコードを 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";
}};
25
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?