代码之家  ›  专栏  ›  技术社区  ›  Alex Luya

如何使用spock框架进行论点捕获?

  •  39
  • Alex Luya  · 技术社区  · 12 年前

    我有一些类似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
                                     }
                                  )            
    }
    

    我想验证 eventBus.fireEvent(..) 使用类型为的事件调用一次 SaveCommentEvent 和施工参数 oldComment 和 newComment .

    代码运行时没有错误,但问题是:

    从中更改封口材料后

    {
       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
      }
    

    代码运行时仍然没有错误?显然,闭包并没有达到我想要的效果,所以问题是:如何进行参数捕获?

    6 回复  |  直到 10 年前
        1
  •  63
  •   Graham Russell Drew Wills    10 年前

    我得到了它:

        SaveCommentEvent firedEvent
    
        given:
         ...
    
        when:
         ....
    
        then:
        1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
        firedEvent instanceof SaveModelEvent
        firedEvent.newModel == newModel
        firedEvent.oldModel == oldModel
    
        2
  •  19
  •   jeremyjjbrown    12 年前
    then:
         1*eventBus.fireEvent(
                                {
                                   it.source.getClass()==SaveCommentEvent;
                                   it.oldComment==oldComment;
                                   it.newComment==newComment
                                 }
                              )            
    

    在您的代码中 it 是一个 Groovy Closure Implicit Variable 对没有字段的模拟事件总线接口的引用。您如何验证它们?

    此外,我认为使用斯波克模拟时发生的事件顺序不一定是直观的。我会把它写在这里,除非它不如 Kenneth Kousen's explanation .

        3
  •  10
  •   ryu1kn    6 年前

    与相同的想法 @Alex Luya 但将断言放在闭包中并使用 assert 在他们每个人身上。查阅 Spock Framework Reference Documentation .

        then:
        1 * eventBus.fireEvent(_) >> {
            def firedEvent = it[0]
            assert firedEvent instanceof SaveModelEvent
            assert firedEvent.newModel == newModel
            assert firedEvent.oldModel == oldModel
        }
    
        4
  •  9
  •   B_Osipiuk    5 年前

    2021(7年后),可以使用groovy(2.5)执行以下操作:

        ...
    
        then:
        1 * eventBus.fireEvent(_) >> { SaveModelEvent event ->
            assert event.newModel == newModel
            assert event.oldModel == oldModel
        }
        0 * _
    

    ..这对我来说更方便,节省了一两行。:)

        5
  •  2
  •   Power    4 年前

    如果您想模拟一个方法的响应并验证同一方法的参数(与捕获参数相同),可以使用Spock的 code constraints (以及其他约束)以部分匹配参数,同时验证方法参数

    1 * list.add({
      verifyAll(it, Person) {
        firstname == 'William'
        lastname == 'Kirk'
        age == 45
      }
    }) >> mockedResponse
    

    PS:解决方案灵感来自 this response 来自@Leonard Brnings

        6
  •  1
  •   T.V. narjess abbassi    7 年前

    在上面@alex luya的回答中,我发现变量 firedEvent 需要 @Shared 注释。

    然后我可以捕获该值,并对闭包之外的值进行检查。