代码在 ScalaTest 中无异常运行的单元测试
Unit testing that code runs without exception in ScalaTest
TL;DR 我有一个任务 [Unit],在 ScalaTest/FlatSpec 中,测试任务是否在给定时间范围内成功的正确方法是什么?
我有一个服务器-客户端架构的应用程序,客户端和服务器之间的交互是非阻塞的。这是通过调用客户端 returning 一个未来来实现的,该未来在服务器完成工作时完成。重要的是,这个 future 不会 return 返回结果,它只是用来表示服务器已经完成:
val notification: Task[Unit] = myServer.alterState("do this")
Await.result(notification.runAsync, 20.seconds)
我想在这里测试的是服务器是否正确地向客户端发送完成通知。我正在使用 ScalaTest 的 FlatSpec 对此进行测试,在我看来,以下应该是一个有效的测试:
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
Await.result(notification.runAsync, 20.seconds)
}
如果服务器回复时间超过 20 秒,Await.result 将抛出异常,测试将捕获该异常并失败。
这是在 flatspec 中执行此类测试的正确方法吗?所有匹配框架似乎都围绕着测试结果的价值,并捕捉预期的异常,但我没有结果 returned,我只是想测试 future 是否成功结束。
您可以使用intercept
方法来验证是否抛出异常。
val notification: Task[Unit] = myServer.alterState("do this")
notification onComplete {
case Failure(_) => fail()
case Success(_) => succeed
}
intercept[TimeoutException] { //you can also use Exception instead of TimeoutException
Await.result(notification.runAsync, 20.seconds)
}
If your code throws the exception, intercept catches it, and the test
succeeds. (You expected it to throw an exception, and it did.)
ScalaFutures
启用断言 Future
在指定的时间段内准备就绪,例如
import org.scalatest._
import org.scalatest.concurrent.ScalaFutures
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
class ServerSpec extends FlatSpec with ScalaFutures {
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
assert(notification.runAsync.isReadyWithin(20 seconds))
}
}
AsyncFlatSpec 允许使用惯用的 Scala 语法,我们可以像这样映射 Future
import org.scalatest._
class ServerSpec extends AsyncFlatSpec {
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
notification.runAsync.map(_ => succeed)
}
}
但请确保服务器设计为超时,否则测试将挂起。
FlatSpec
和 Await
可以明确断言 no exception 应该像这样抛出
import org.scalatest._
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
class ServerSpec extends FlatSpec with Matchers {
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
noException should be thrownBy Await.result(notification.runAsync, 20.seconds)
}
}
就我个人而言,我会推荐 AsyncFlatSpec
方法。
TL;DR 我有一个任务 [Unit],在 ScalaTest/FlatSpec 中,测试任务是否在给定时间范围内成功的正确方法是什么?
我有一个服务器-客户端架构的应用程序,客户端和服务器之间的交互是非阻塞的。这是通过调用客户端 returning 一个未来来实现的,该未来在服务器完成工作时完成。重要的是,这个 future 不会 return 返回结果,它只是用来表示服务器已经完成:
val notification: Task[Unit] = myServer.alterState("do this")
Await.result(notification.runAsync, 20.seconds)
我想在这里测试的是服务器是否正确地向客户端发送完成通知。我正在使用 ScalaTest 的 FlatSpec 对此进行测试,在我看来,以下应该是一个有效的测试:
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
Await.result(notification.runAsync, 20.seconds)
}
如果服务器回复时间超过 20 秒,Await.result 将抛出异常,测试将捕获该异常并失败。
这是在 flatspec 中执行此类测试的正确方法吗?所有匹配框架似乎都围绕着测试结果的价值,并捕捉预期的异常,但我没有结果 returned,我只是想测试 future 是否成功结束。
您可以使用intercept
方法来验证是否抛出异常。
val notification: Task[Unit] = myServer.alterState("do this")
notification onComplete {
case Failure(_) => fail()
case Success(_) => succeed
}
intercept[TimeoutException] { //you can also use Exception instead of TimeoutException
Await.result(notification.runAsync, 20.seconds)
}
If your code throws the exception, intercept catches it, and the test succeeds. (You expected it to throw an exception, and it did.)
ScalaFutures
启用断言 Future
在指定的时间段内准备就绪,例如
import org.scalatest._
import org.scalatest.concurrent.ScalaFutures
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
class ServerSpec extends FlatSpec with ScalaFutures {
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
assert(notification.runAsync.isReadyWithin(20 seconds))
}
}
AsyncFlatSpec 允许使用惯用的 Scala 语法,我们可以像这样映射 Future
import org.scalatest._
class ServerSpec extends AsyncFlatSpec {
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
notification.runAsync.map(_ => succeed)
}
}
但请确保服务器设计为超时,否则测试将挂起。
FlatSpec
和 Await
可以明确断言 no exception 应该像这样抛出
import org.scalatest._
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
class ServerSpec extends FlatSpec with Matchers {
"Server" should "notify client upon completion" in {
val notification: Task[Unit] = myServer.alterState("do this")
noException should be thrownBy Await.result(notification.runAsync, 20.seconds)
}
}
就我个人而言,我会推荐 AsyncFlatSpec
方法。