gpt4 book ai didi

ScalaTest:断言阻塞语句

转载 作者:行者123 更新时间:2023-12-04 02:20:38 26 4
gpt4 key购买 nike

我正在使用一些带有 blocking 语句的代码:

blocking {
Thread.sleep(10*1000)
}

有没有办法断言给出了这个blocking语句?或者换句话说:如果有人删除了 blocking 语句,我可以编写一个失败的测试吗?

更新如何在 Future 中使用断言阻塞?

最佳答案

尝试玩BlockContext .

你应该得到这样的东西:

var blocked = false // flag to detect blocking

val oldContext = BlockContext.current
val myContext = new BlockContext {
override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
blocked = true
oldContext.blockOn(thunk)
}
}

BlockContext.withBlockContext(myContext) {
blocking {} // block (or not) here
}

assert(blocked) // verify that blocking happened

如果您想测试包装在 Future 中的代码,请更新使其工作(评论跟进)

当您构建Future 时,它的工厂方法采用代码块(函数)来显式执行上下文 em> 隐式(通常是 scala.concurrent.ExecutionContext.Implicits.global)。

稍后的代码块将被安排到执行上下文,并将在其中一个线程中运行。

现在,如果您只是将阻塞代码段包装到传递给 BlockContext.withBlockContext 的代码块内的 Future 中,就像您在评论中建议的那样:

BlockContext.withBlockContext(myContext) {
Future {
blocking { Thread.sleep(100) }
}
}

...这将不起作用,因为您当前的线程只会执行 Future 构造,传递给 Future 的实际代码将在相关执行上下文的线程中执行(BlockContext.withBlockContext 检测当前线程中的阻塞

话虽如此,我可以建议您做以下三件事之一:

  1. 不要将要测试的代码包装到 Future 中。如果你想测试一段代码是否使用了blocking - 就这么做吧。
    编写一个函数并测试它,你可以在生产中将它传递给 Future

  2. 假设出于某种原因您无法避免在测试中创建 Future。在这种情况下,您将不得不篡改构建 future 时使用的执行上下文。
    此代码示例演示了如何做到这一点(重用我原始示例中的 blockedmyContext):


// execution context that submits everything that is passed to it to global execution context
// it also wraps any work submited to it into block context that records blocks
implicit val ec = new ExecutionContext {
override def execute(runnable: Runnable): Unit = {
ExecutionContext.Implicits.global execute new Runnable {
override def run(): Unit = {
BlockContext.withBlockContext(myContext) {
runnable.run()
}
}
}
}
override def reportFailure(t: Throwable): Unit = {
ExecutionContext.Implicits.global.reportFailure(t)
}
}

// this future will use execution context defined above
val f = Future {
blocking {} // block (or not) here
}
Await.ready(f, scala.concurrent.duration.Duration.Inf)

assert(blocked)
  1. 如果你的 Future 是间接创建的,例如,作为调用你在测试中运行的其他函数的结果,那么你将不得不以某种方式(可能使用依赖注入(inject))拖动你的模拟执行上下文到创建 Future 的任何地方,并在那里使用它来构造它。

如您所见,第一个选项是最简单的,如果可以,我建议您坚持使用。

关于ScalaTest:断言阻塞语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25970926/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com