概要
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になります