【问题标题】:How to do argument capture with spock framework?如何使用 spock 框架进行参数捕获?
【发布时间】:2014-04-02 09:39:49
【问题描述】:

我有一些这样的 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,构造参数为oldCommentnewComment

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

更改关闭内容后
{
   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
  }

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

【问题讨论】:

    标签: spock


    【解决方案1】:

    我明白了:

        SaveCommentEvent firedEvent
    
        given:
         ...
    
        when:
         ....
    
        then:
        1 * eventBus.fireEvent(_) >> {arguments -> firedEvent=arguments[0]}
        firedEvent instanceof SaveModelEvent
        firedEvent.newModel == newModel
        firedEvent.oldModel == oldModel
    

    【讨论】:

    • 或者将原代码中的;替换为&amp;&amp;。 (代码参数约束需要返回truefalse 取决于它们是否匹配。)
    • 我发现无论在哪里定义变量,都无法在闭包之外访问捕获的参数。
    • 使用这种方法的主要好处不仅仅是替换;在原始代码中使用 && 可以让您获得更精细的错误消息 - 您确切知道什么条件失败了
    • Spock 似乎混淆了作为模拟返回值捕获的参数。它如何对其他人起作用? @AlexLuya
    • @Vishal 闭包将返回最后一行作为模拟的返回值,因此如果返回类型与参数类型不同,那么您应该从关闭
    【解决方案2】:
    then:
         1*eventBus.fireEvent(
                                {
                                   it.source.getClass()==SaveCommentEvent;
                                   it.oldComment==oldComment;
                                   it.newComment==newComment
                                 }
                              )            
    

    在您的代码中,itGroovy Closure Implicit Variable 对没有字段的模拟 eventBus 接口的引用。你怎么能验证他们?

    另外,我认为使用 Spock Mocks 必须发生的事件顺序不一定是直观的。我会把它写在这里,除非它不如Kenneth Kousen's explanation

    【讨论】:

    • @jeremyjjbrown 如果我没记错的话,您提供的代码并非 100% 正确。具体来说,只有在 it.newComment==newComment 检查未通过时,测试才会失败。前两次检查不会对测试的通过或失败产生任何影响。这就是@PeterNiederwieser 在他的评论中暗示的内容
    【解决方案3】:

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

    【讨论】:

    • 感谢@mikerodent,我的意图是链接到多个assertions 示例;所以链接在这方面看起来是正确的。至于 jeremyjjbrown 的回答,我不确定……@geoand 指出并非所有断言都在生效。我不再有 sn-p 进行实验:p
    • 啊,“不是很有帮助。幸运的是,我们可以做得更好:”下的东西……我没有发现。也是的,@geoand 的观点是正确的。我的错。
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-05
        • 1970-01-01
        • 2013-04-26
        • 1970-01-01
        • 2013-07-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多