Unit testing 使用指定的超时验证Spock模拟
在Mockito中,可以选择验证是否调用了mock方法,并为此验证指定超时(Unit testing 使用指定的超时验证Spock模拟,unit-testing,testing,mocking,spock,Unit Testing,Testing,Mocking,Spock,在Mockito中,可以选择验证是否调用了mock方法,并为此验证指定超时(VerificationWithTimeout),例如: verify(mock, timeout(200).atLeastOnce()).baz(); Spock中是否有类似功能?Spock中没有类似功能。(PollingConditions只能用于条件,不能用于交互。)最接近的方法是在then块中添加sleep()语句: when: ... then: sleep(200) (1.._) * mock.baz()
VerificationWithTimeout
),例如:
verify(mock, timeout(200).atLeastOnce()).baz();
Spock中是否有类似功能?Spock中没有类似功能。(
PollingConditions
只能用于条件,不能用于交互。)最接近的方法是在then
块中添加sleep()
语句:
when:
...
then:
sleep(200)
(1.._) * mock.baz()
我试图使用PollingConditions来满足类似的场景(这没有帮助),但却在斯波克的实验中找到了满足感。要验证在给定的超时时间内,函数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()
}
def“验证200毫秒内至少发生一次交互”(){
鉴于:
def结果=新阻塞变量(0.2)//200ms
SomeService someServiceMock=Mock()
someServiceMock.method()>>{
result.set(真)
}
ClassBeingTested clazz=新的ClassBeingTested(someService:someServiceMock)
什么时候:
clazz.someMethod()
然后:
result.get()
}
当设置结果时,阻塞条件将得到满足,result.get()必须返回true才能通过该条件。如果在200ms内设置失败,测试将失败并出现超时异常。使用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 * _
}这与问题所问的不完全一样,但我发现使用变量会更简洁一些。如果除了交互之外还有其他条件要异步测试,那么可以在模拟创建时声明交互,然后使用
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
}
}
}
彼得-你的解决方案导致我总是要等200毫秒。在这种情况下,我更喜欢使用Mockito,因为它只是工作:)而不是当前。这个功能听起来很臭,我正试图抵制实现臭烘烘的模拟功能。在这种情况下,我进行了集成测试,我将消息发送到队列,并检查是否收到消息-我不认为这是臭烘烘的味道是使用模拟进行集成测试。我喜欢这种猜测-没有看过代码,但已经知道它是错误的。。。