当我分别运行runAsyncWithMock
测试时,它会等待3秒钟,直到模拟的执行完成为止,而不是像其他两个测试一样被终止。
我不知道为什么。
有趣的是:
Runnables
测试中,CompletableFuture.runAsync
连续执行了多个runAsyncWithMock
时,只有第一个等待,其他则没有。runAsyncWithMock
测试,则在执行整个规范时,每个测试都将运行3秒钟。知道我怎么了吗?
我的配置:
回购包含整个Gradle项目以进行复制:
https://github.com/lobodpav/CompletableFutureMisbehavingTestInSpock
有问题的测试代码:
@Stepwise
class SpockCompletableFutureTest extends Specification {
def runnable = Stub(Runnable) {
run() >> {
println "${Date.newInstance()} BEGIN1 in thread ${Thread.currentThread()}"
sleep(3000)
println "${Date.newInstance()} END1 in thread ${Thread.currentThread()}"
}
}
def "runAsyncWithMock"() {
when:
CompletableFuture.runAsync(runnable)
then:
true
}
def "runAsyncWithMockAndClosure"() {
when:
CompletableFuture.runAsync({ runnable.run() })
then:
true
}
def "runAsyncWithClass"() {
when:
CompletableFuture.runAsync(new Runnable() {
void run() {
println "${Date.newInstance()} BEGIN2 in thread ${Thread.currentThread()}"
sleep(3000)
println "${Date.newInstance()} END2 in thread ${Thread.currentThread()}"
}
})
then:
true
}
}
答案 0 :(得分:1)
这是由https://github.com/spockframework/spock/blob/master/spock-core/src/main/java/org/spockframework/mock/runtime/MockController.java中的synchronized
方法引起的,当执行模拟时,它通过handle
方法进行委托。该规范还使用synchronized
方法,在这种情况下可能使用leaveScope
,因此被休眠Stub方法阻止。
由于这是一个线程交错问题,我猜想runAsyncWithMockAndClosure
中的附加闭包将存根方法的执行移到了leaveScope
之后,从而改变了顺序/阻塞。
答案 1 :(得分:0)
哦,刚才写完最后一条评论后,我看到了一个不同:
您使用localStorage.setItem('nameoffield',value);
(初次尝试时没有使用),我几乎从未使用过它,因为它会在功能方法之间建立依赖关系(不良,不良的测试实践)。虽然我不能说为什么只有在运行第一种方法时,这种效果才会由您描述,但是我可以告诉您,删除注释可以解决此问题。
P.S .:使用@Stepwise
时,您甚至不能单独执行第二种或第三种方法,因为运行程序将始终首先运行前面的方法,因为-好吧,据说该规范是逐步执行的。 ;-)
更新:我可以使用@Stepwise
简要地重现该问题,但是重新编译后,无论有没有注释,现在都不再发生。