Spockを使用してStatic Methodをテストする方法

4191 ワード

Spock簡易使用説明


Spockを用いたテストプログラムの開発は,BDDの開発プロセスを支援し,JUnitとの適合や内蔵Data Driven機能などの特性に加えて,Mockの機能を内蔵しているという利点がある.Spockが提供するMock機能は、使用上かなり簡潔で、次の例のソースコードです.
def "Spock  "() {
    given:
    def mockClass = Mock(ConcreteClass)
    def mockInterface1 = Mock(IInjection)
    IInjection mockInterface2 = Mock()
    Processor tester = new Processor(mockClass)

    mockInterface2.getInfo() >> { " " }

    when:
    tester.run(mockInterface1)

    then:
    1 * mockClass.start()
    1 * mockInterface1.getInfo() >> { " " }
    _ * mockClass.process(_) >> { mockInterface2 }
    1 * mockInterface2.setData(_)
    1 * mockClass.end()
}

以上のソースコードから、Mock()メソッドを使用すれば指定したオブジェクトをMockすることができるプログラムが見られるとともに、MockするオブジェクトをMock()メソッド(3,4行目)に転送する方法と、Mock()メソッドを使用してインスタンス(5行目)を作成する方法の2つの弾力性のある宣言方式が提供される.2つ目のJava-likeの構文は、主にソースコードを編集するときにIDEがより良いサポートを提供することを望んでおり、実行時に発生するMockオブジェクトのInstanceを宣言された型別で判定します.
Spockが提供するMock機能のもう一つのポイントは、Interfaceだけでなく、一般的なClassにも使用できることです.このようにシステム設計を行う際には,「別々にテストする方法があるかどうか」という問題に移行することなく,大量のIoCを設計に用いることができ,過剰な設計が形成される.Mock Classの前に、プロジェクトはcglib-nodepとobjenesisの2つのライブラリを参照する必要がありますのでbuild.gradleのdependenciesは、以下のように示すべきです.
dependencies {
    testCompile 'org.codehaus.groovy:groovy-all:2.4.4'
    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
    testCompile 'org.objenesis:objenesis:2.2'
    testCompile 'cglib:cglib-nodep:3.1'
}

公式文書の説明によれば、ターゲットClassがその周辺Objectと相互作用するプロセスがシーケンス図のように表現された設計内容に合致するかどうかを検証するには、サンプルプログラムで例示された内容を使用します.使用する文法仕様は、[インタラクティブな回数]*[インタラクティブなマーク],1*mockClass.start()は認証プロセスです.runはConcreteClassを呼び出したかどうか.start()そしてプロセス全体runの実行中に呼び出されるのは1回だけです.
例示的なプログラムから、Spockが提供するMock機能は、Class間のインタラクティブなプロセスを検証するだけでなく、Stubの能力も備えていることがわかります.呼び出した内容に基づいて対応する動作を提供することができ,テストプログラムの柔軟性が向上した.サンプルプログラムの8行目のように、プログラムがmockInterface 2を呼び出す.getInfo()の場合、「2番テスト文字列」の内容が固定されます.15行目、16行目では、プロセスを表す.runの実行中に,この2つのターゲット関数を呼び出すと取得する内容がある.

静的メソッドをロックする方法


Spockは多くの優れた特性を提供しているが,米国では不足している点は,現在のバージョンではMock静的方法がないことである.ネット上でいくつかの議論を見た後、PowerMockはSpockと組み合わせてこの問題を解決するためのフレームワークのようだ.さらに、PowerMockが提供するスイートの種類は多く、いくつかの主流のテストフレームワークと統合された機能が含まれていることがわかります.Gradleで対応するスイートをどのように設定するかは、SpockとPowerMockを連携させることが敷居になります.
基本的にSpockでPowerMockを使用して静的方法をMockするには、JUnit、Mockito、PowerMockといういくつかのフレームワークが使用され、buildが設定される.gradleコンテンツはさらに厄介です.テストプログラムでは,この4つのフレームワークを統合して,Mock静的手法の目的を達成できるようにすることも,苦労の一つである.
現在、ネット上で調べられている情報は断片的であるため、ここでは関連する情報を統合し、今後の研究の起点としている.以下はbuild.gradleの内容:
apply plugin: 'java'
apply plugin: 'groovy'

dependencies {
    testCompile 'org.codehaus.groovy:groovy-all:2.4.4'
    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
    testCompile 'org.objenesis:objenesis:2.2'
    testCompile 'cglib:cglib-nodep:3.1'
    testCompile 'org.mockito:mockito-core:1.10.19'
    testCompile 'org.powermock:powermock-api-mockito:1.6.2'
    testCompile 'org.powermock:powermock-module-junit4:1.6.2'
    testCompile 'org.powermock:powermock-module-junit4-rule:1.6.2'
    testCompile 'org.powermock:powermock-classloading-xstream:1.6.2'
}

以上のスイートは、所属フレームワークの更新状況に応じて対応するバージョン番号を調整する必要があります.
テストプログラムで、次のClassがある場合:
public class TestClass {

    public static String staticMethod() {
        return null;
    }

}

テストプログラムは、静的メソッドのテストを以下のように行う必要があります.
import org.junit.Rule
import org.mockito.Mockito
import org.powermock.api.mockito.PowerMockito
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.rule.PowerMockRule
import spock.lang.Specification

@PrepareForTest([TestClass.class])
class MockStaticMethodSpec extends Specification {

    @Rule
    PowerMockRule mPowerMockRule = new PowerMockRule();

    def " "() {
        setup :
        PowerMockito.mockStatic(TestClass.class)

        when :
        Mockito.when(TestClass.staticMethod()).thenReturn(" ")

        then :
        TestClass.staticMethod() == " "
    }

}