groovy 如何在超时时间内从PollingConditions.中退出?

kzipqqlq  于 8个月前  发布在  其他
关注(0)|答案(2)|浏览(61)

我有PollingConditions,它探测系统中的某个数值,以获得某个精确值,例如:

def pollingConditions = new PollingConditions()
def status = 5; 
         ..... //schedule change of status in some background task
        pollingConditions.within(10,{
        //when status is 20, test must fail right away as it will never become 10 by the business rules
           assert status == 10;
        })

现在可以等到status==10,除非状态变为例如。20,在这种情况下,它不可能满足某些状态转换规则定义的Assert。在这种情况下,等待10秒的完整时间是没有意义的,我可以立即失败的测试。
在这种情况下,我怎么能立即通过测试?

ddhy6vgd

ddhy6vgd1#

不带参数的PollingConditions构造函数将默认延迟设置为0.1秒,超时设置为1秒。也就是说,您的调用不会等待整个10秒,而是在迭代之间仅等待0.1秒。这对你的目的来说应该足够了。
要进行更细粒度的控制,有时可以使用

PollingConditions pc = new PollingConditions(timeout : 3, delay : 0.2, factor : 1)
pc.eventually { /* ... */ }

或者简单地在不带构造函数参数的示例上使用setter。
下面是的源代码

顺便说一句,如果你静态地输入你的PollingConditions示例,你不再需要使用assert,而可以使用正常的Spock条件。因此,要么直接使用new PollingConditions().within(/* ... */),要么像我上面的例子一样,将变量声明为PollingConditions pc而不是def pc

在评论中澄清后更新:只是为了向你展示你提供一个完整的复制器是多么的微不足道,我将提供一个来证明你的“我不能”是胡说八道:

package de.scrum_master.stackoverflow.q76919522

import spock.lang.Specification
import spock.lang.Unroll
import spock.util.concurrent.PollingConditions

import static de.scrum_master.stackoverflow.q76919522.PollingConditionsWithExitConditionTest.StateMachine.State.*

class PollingConditionsWithExitConditionTest extends Specification {
  static class StateMachine {
    enum State { AWAKE, SLEEPING, DEAD }

    State state
  }

  @Unroll("wake up from state #state")
  def "state machine must wake up before timeout"() {
    given:
    def stateMachine = new StateMachine(state: state)

    expect:
    new PollingConditions().within 10, {
      [AWAKE, DEAD].contains(stateMachine.state)
    }
    stateMachine.state == AWAKE

    where:
    state << [AWAKE, SLEEPING, DEAD]
  }
}

至于手头的问题,从轮询条件中脱身的解决方案非常简单:只需要测试这两个条件,一个是实际等待的条件(在我的示例AWAKE中),另一个是应该退出的条件(在我的示例DEAD)中)。然后简单地添加另一个条件来重新检查AWAKE条件。
效果正是你想要的:AWAKEDEAD的测试快速终止,但SLEEPING的测试等待整整10秒:

Groovy Web Console中尝试。

erhoui1w

erhoui1w2#

虽然@kriegaex回答工作,我想提一下,你可以从一个关闭返回。这样你就可以把救助和正常情况分开,保存自己的麻烦,把它们都放进一个班轮。

import spock.lang.*
import spock.util.concurrent.PollingConditions

class ASpec extends Specification {
  def "hello world"() {
    given:
    def bailout = true
    def x,y,z = 0

    expect:
    new PollingConditions().eventually {
      if (bailout) return
      // actual conditions
      x == 1
      y == 2
      z == 3
    }
  }
}

Groovy Web Console中尝试。

相关问题