web-dev-qa-db-ja.com

spockフレームワークで引数をキャプチャするにはどうすればよいですか?

私はいくつかの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
  }
_

それでも、コードはエラーなしで実行されますか?どうやらクロージャーは私が望むことをしなかったので、問題は次のとおりです。

22
Alex Luya

わかった:

    SaveCommentEvent firedEvent

    given:
     ...

    when:
     ....

    then:
    1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
    firedEvent instanceof SaveModelEvent
    firedEvent.newModel == newModel
    firedEvent.oldModel == oldModel
40
Alex Luya
then:
     1*eventBus.fireEvent(
                            {
                               it.source.getClass()==SaveCommentEvent;
                               it.oldComment==oldComment;
                               it.newComment==newComment
                             }
                          )            

あなたのコードではitGroovy Closure Implicit Variable フィールドのないモックeventBusインターフェースへの参照です。それらをどのように確認できますか?

また、Spock Mocksを使用するために発生しなければならないイベントの順序は、必ずしも直感的ではないと思います。 Kenneth Kousenの説明 ほど良くない場合を除いて、ここに書きます。

9
jeremyjjbrown

@ 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
    }
1
ryu1kn

上記の@ alex-luyaからの回答で、変数firedEventには@Sharedアノテーションが必要であることがわかりました。

次に、値を取得して、クロージャーの外側の値に対してチェックを実行できます。

1
Werd