私はいくつかのJavaこのようなものを持っています:
_public interface EventBus{
void fireEvent(GwtEvent<?> event);
}
public class SaveCommentEvent extends GwtEvent<?>{
private finalComment oldComment;
private final Comment newComment;
public SaveCommentEvent(Comment oldComment,Comment newComment){
this.oldComment=oldComment;
this.newComment=newComment;
}
public Comment getOldComment(){...}
public Comment getNewComment(){...}
}
_
次のようなコードをテストします。
_ def "...."(){
EventBus eventBus=Mock()
Comment oldComment=Mock()
Comment newCommnet=Mock()
when:
eventBus.fireEvent(new SaveCommentEvent(oldComment,newComment))
then:
1*eventBus.fireEvent(
{
it.source.getClass()==SaveCommentEvent;
it.oldComment==oldComment;
it.newComment==newComment
}
)
}
_
タイプSaveCommentEvent
と構築パラメーターoldComment
およびnewComment
のイベントでeventBus.fireEvent(..)
が1回呼び出されることを確認したいと思います。
コードはエラーなしで実行されますが、問題は次のとおりです。
からクロージャーのものを変更した後
_{
it.source.getClass()==SaveCommentEvent;
it.oldComment==oldComment; //old==old
it.newComment==newComment //new==new
}
_
に
_ {
it.source.getClass()==Other_Class_Literal;
it.oldComment==newComment; //old==new
it.newComment==oldComment //new==old
}
_
それでも、コードはエラーなしで実行されますか?どうやらクロージャーは私が望むことをしなかったので、問題は次のとおりです。
わかった:
SaveCommentEvent firedEvent
given:
...
when:
....
then:
1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
firedEvent instanceof SaveModelEvent
firedEvent.newModel == newModel
firedEvent.oldModel == oldModel
then:
1*eventBus.fireEvent(
{
it.source.getClass()==SaveCommentEvent;
it.oldComment==oldComment;
it.newComment==newComment
}
)
あなたのコードではit
は Groovy Closure Implicit Variable フィールドのないモックeventBusインターフェースへの参照です。それらをどのように確認できますか?
また、Spock Mocksを使用するために発生しなければならないイベントの順序は、必ずしも直感的ではないと思います。 Kenneth Kousenの説明 ほど良くない場合を除いて、ここに書きます。
@ Alex Luya と同じ考えですが、アサーションをクロージャーに入れ、それぞれにassert
を使用します。 cf. Spock Frameworkリファレンスドキュメント 。
then:
1 * eventBus.fireEvent(_) >> {
def firedEvent = it[0]
assert firedEvent instanceof SaveModelEvent
assert firedEvent.newModel == newModel
assert firedEvent.oldModel == oldModel
}
上記の@ alex-luyaからの回答で、変数firedEvent
には@Shared
アノテーションが必要であることがわかりました。
次に、値を取得して、クロージャーの外側の値に対してチェックを実行できます。