Модульное тестирование этого кода без исключения выполняется в ScalaTest - PullRequest
1 голос
/ 09 мая 2019

TL; DR У меня есть задание [Unit], в ScalaTest / FlatSpec, как правильно проверить, успешно ли выполнено задание за определенный период времени?

У меня есть приложение с сервером-клиентомВ архитектуре взаимодействие между клиентом и сервером не блокируется.Это реализуется с помощью вызовов клиента, возвращающих будущее, которое завершается, когда сервер завершил работу.Важно, что это будущее не возвращает результат, оно просто используется для указания того, что сервер завершил:

val notification: Task[Unit] = myServer.alterState("do this")
Await.result(notification.runAsync, 20.seconds)

Я хочу проверить, что сервер правильно отправляет клиенту уведомления о завершении.,Я тестирую это с FlatSpec от ScalaTest, и мне кажется, что следующий тест должен быть действительным:

"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?Кажется, что вся подходящая структура ориентирована на тестирование значения результатов и отслеживание ожидаемых исключений, но у меня нет результата, возвращаемого, я просто хочу проверить, что будущее заканчивается успешно.

Ответы [ 2 ]

1 голос
/ 09 мая 2019

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 может утверждать явно без исключения должно быть выброшено так

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 метод.

0 голосов
/ 09 мая 2019

Вы можете использовать метод 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)
  }

Если ваш код выдает исключение, перехват перехватывает его, и тест завершается успешно.(Вы ожидали, что это вызовет исключение, и это произошло.)

Более подробную информацию можно найти здесь или здесь

...