我有
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 bussiness rules
assert status == 10;
})
现在可以等到
status==10
,除非状态变成例如20
,在这种情况下它不可能满足某些状态转换规则定义的断言。在这种情况下,等待整整 10 秒是没有意义的,我可能会立即通过测试。
这种情况如何才能立即通过测试?
不带参数的
PollingConditions
构造函数设置默认延迟 0.1 秒和超时 1 秒。也就是说,您的调用不会等待完整的 10 秒,而只会在迭代之间等待 0.1 秒。这应该足以满足您的目的。
为了更细粒度的控制,你可以使用像
这样的时间def pc = new PollingConditions(timeout : 3, delay : 0.2, factor : 1)
pc.eventually { /* ... */ }
或者简单地在没有构造函数参数的情况下创建的实例上使用设置器。
这是
的源代码在评论中澄清后更新:只是为了向您展示提供完整的复制器是多么微不足道,我将提供一个来证明您的“我不能”是无稽之谈:
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
条件。
效果正是您想要的:
AWAKE
和DEAD
测试很快终止,但SLEEPING
等待整整10秒:
在 Groovy Web Console 中尝试一下。