LoginSignup
2
2

More than 5 years have passed since last update.

SpockのConfineMetaClassChangesアノテーションを検証する

Posted at

概要

SpockのConfineMetaClassChangesアノテーションは、mockしたクラスやインスタンスを
mock前の状態に戻してくれるそうなので検証してみました
http://spockframework.org/spock/javadoc/1.0/spock/util/mop/ConfineMetaClassChanges.html

サンプル

featureにアノテーションを付ける場合

import spock.lang.Specification
import spock.util.mop.ConfineMetaClassChanges

class HogeSpec extends Specification {
    def "groovyで処理をオーバーライドする"() {
        given:
        // getHogeメソッドの戻り値をfugaに変える
        Hoge.metaClass.getHoge = {
            "fuga"
        }

        when:
        // getHogeを実行する
        def hoge = new Hoge().getHoge()

        then:
        // getHogeの値がfugaに変わっているはず
        hoge == "fuga"
    }

    def "groovyでオーバーライドされた処理を実行する"() {
        given:
        // ここではHogeクラスを書き換えない

        when:
        // getHogeを実行する
        def hoge = new Hoge().getHoge()

        then:
        // getHogeの値はhogeのままと思いきやfugaに変わったまま
        hoge == "fuga"
    }

    @ConfineMetaClassChanges(Hoge)
    def "再度オーバーライドするけどConfineMetaClassChangesアノテーションがついてる"() {
        given:
        // getHogeメソッドの戻り値をpiyoに変える
        Hoge.metaClass.getHoge = {
            "piyo"
        }

        when:
        // getHogeを実行する
        def hoge = new Hoge().getHoge()

        then:
        // getHogeの値がpiyoに変わっているはず
        hoge == "piyo"
    }

    def "ConfineMetaClassChangesアノテーション付きでオーバーライドされた処理を実行する"() {
        given:
        // ここではHogeクラスを書き換えない

        when:
        // getHogeを実行する
        def hoge = new Hoge().getHoge()

        then:
        // さっきはメソッド間で処理が変わってなかったので
        // getHogeの値はpiyoのままと思いきや
        // piyoへの変更は破棄されてfugaに戻っている
        hoge == "fuga"
    }

    class Hoge {
        def String getHoge() {
            "hoge"
        }
    }
}

そのままSpockのテストとして実行するとTestSuccessになります

クラスにアノテーションをつける場合

class Fuga {
    def String getFuga() {
        "fuga"
    }
}
import spock.lang.Specification
import spock.util.mop.ConfineMetaClassChanges

@ConfineMetaClassChanges(Fuga)
class FirstTestSpec extends Specification {

    def "groovyで処理をオーバーライドする"() {
        given:
        // getFugaメソッドの戻り値をfugaに変える
        Fuga.metaClass.getFuga = {
            "piyo"
        }

        when:
        // getFugaを実行する
        def fuga = new Fuga().getFuga()

        then:
        // getFugaの値がfugaに変わっているはず
        fuga == "piyo"
    }

    def "groovyでオーバーライドされた処理を実行する"() {
        given:
        // ここではFugaクラスを書き換えない

        when:
        // getFugaを実行する
        def fuga = new Fuga().getFuga()

        then:
        // getFugaの値はpiyoのまま
        fuga == "piyo"
    }
}
import spock.lang.Specification

class SecondTestSpec extends Specification {

    def "再度オーバーライドされた処理を実行する"() {
        given:
        // ここではFugaクラスを書き換えない

        when:
        // getFugaを実行する
        def fuga = new Fuga().getFuga()

        then:
        // ここではpiyoへの変更は破棄されてfugaに戻っている
        fuga == "fuga"
    }
}

FirstTestSpec -> SecondTestSpecの順で通して実行するとTestSuccessになります

今回作成したコード

2
2
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
2
2