在Mockito中,可以选择验证是否已调用mock方法,并为此验证指定超时(VerificationWithTimeout
),例如:
verify(mock, timeout(200).atLeastOnce()).baz();
在Spock中有没有相当于这样的功能?
答案 0 :(得分:7)
我试图使用PollingConditions来满足类似的场景(这并没有帮助),但却在Spock的BlockingVariables中找到了满足感。要验证在给定的超时时间内函数ClassBeingTested.method()中至少调用一次SomeService.method():
def "verify an interaction happened at least once within 200ms"(){
given:
def result = new BlockingVariable<Boolean>(0.2) // 200ms
SomeService someServiceMock = Mock()
someServiceMock.method() >> {
result.set(true)
}
ClassBeingTested clazz = new ClassBeingTested(someService: someServiceMock)
when:
clazz.someMethod()
then:
result.get()
}
设置结果后,将满足阻塞条件,并且result.get()必须为要传递的条件返回true。如果未能在200ms内设置,则测试将因超时异常而失败。
答案 1 :(得分:6)
Spock没有相应的内容。 (PollingConditions
只能用于条件,而不能用于互动。)您最接近的是在sleep()
块中添加then
语句:
when:
...
then:
sleep(200)
(1.._) * mock.baz()
答案 2 :(得分:1)
使用PollingConditions和布尔变量,以下示例评估函数,直到它满足交互。
def "test the config watcher to reload games if a new customer directory is added"() {
given:
def conditions = new PollingConditions(initialDelay: 1, timeout: 60, factor: 1.25)
def mockGameConfigLoader = Mock(GameConfigLoader)
def gameConfigWatcher= new GameConfigWatcher(mockGameConfigLoader)
boolean gamesReloaded = false
when:
conditions.eventually {
gameConfigWatcher.listenEvents()
assert gamesReloaded
}
then:
1 * mockGameConfigLoader.loadAllGameConfigs() >> {
gamesReloaded = true
}
0 * _
}
答案 3 :(得分:0)
这并不能完全解决问题,但我发现使用变量更干净。如果除了交互之外还具有其他要异步测试的条件,则可以在模拟创建时声明交互,然后使用PollingConditions
测试其他条件。 PollingConditions
要么会失败要么无法通过测试,或者直到条件通过才阻止,因此在测试交互之前,应已调用该方法:
@MicronautTest
class KernelManagerTest extends Specification {
@Inject
KernelManager kernelManager
//create conditions
PollingConditions conditions = new PollingConditions(timeout: 10, initialDelay: 1)
class Exits {
static createKernel (String[] args) {
System.exit(args[0].toInteger())
}
}
def "handles a system exit from within kernel"() {
given:
// set custom kernel
kernelManager.kernelClass = Exits
// create custom logger
kernelManager.log = Mock(Logger) {
1 * warn("Kernel exited unexpectedly.", _ as UnexpectedExitException)
}
when:
// create new kernel (exit 1)
kernelManager.startNewKernel("1")
then:
conditions.eventually {
kernelManager.kernelInstances.size() == 0
kernelManager.kernelThreads.size() == 0
}
}
}