testing - 当由 CompletableFuture 运行时,在 Spock 的 Mock 等待中休眠

标签 testing groovy spock

当我单独运行 runAsyncWithMock 测试时,它会等待 3 秒直到模拟的执行完成,而不是像其他 2 个测试那样被终止。

我不明白为什么。

有趣的是:

  1. runAsyncWithMock测试中,CompletableFuture.runAsync连续执行多个Runnable时,只有第一个等待,其他不等待.
  2. 当有多个重复的 runAsyncWithMock 测试时,在执行整个规范时,每个测试都会运行 3 秒。
  3. 当使用 Class 实例而不是 Mock 时,测试会立即完成。

知道我错了什么吗?

我的配置:

  • macOS Mojave 10.14.6
  • Spock 1.3-groovy-2.4
  • 常规 2.4.15
  • JDK 1.8.0_201

包含用于复制的整个 Gradle 项目的 repo:

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
    }
}

最佳答案

这是由 https://github.com/spockframework/spock/blob/master/spock-core/src/main/java/org/spockframework/mock/runtime/MockController.java 中的 synchronized 方法引起的当执行模拟时,它通过 handle 方法进行委托(delegate)。该规范还使用了 synchronized 方法,在本例中可能是 leaveScope,因此被休眠 Stub 方法阻塞。

由于这是一个线程交错问题,我猜测 runAsyncWithMockAndClosure 中的附加闭包将 stub 方法的执行移到了 leaveScope 之后,从而改变了顺序/阻塞。

关于testing - 当由 CompletableFuture 运行时,在 Spock 的 Mock 等待中休眠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57869239/

相关文章:

testing - Spock MissingMethodException

java - 如何在 Java 中获得最好的代码覆盖率?

ruby-on-rails - 自动测试无限循环

groovy - SOAPUI:如何从外部文件中包含 Groovy 脚本

java - Groovy/Grails 包含小写字母

java - 在最近一小时内修改过的目录中查找文件

Groovy/Spock BUG!将变量传递给闭包时

unit-testing - Scala 测试 : What's the status and relationship of SUnit, ScalaTest、ScalaCheck、Specs 和 ParTest?

ruby-on-rails-3 - 为 lib 文件夹中的模块编写测试