#scala #future #scalatest
Вопрос:
Для проверки будущей ценности Scala я использую этот код :
"Simple Test" should "Test Future" in {
val futureData1: Future[Data] = MakeData()
futureData1 map { data => {
assert(data.value == 2)
}
}
}
Это ведет себя так, как ожидалось, как проверить значения, содержащиеся в двух фьючерсах ?
Например, как правильно изменить ниже, чтобы проверить два будущих:
"Simple Test" should "Test Future" in {
val futureData1: Future[Data] = MakeData()
val futureData1: Future[Data] = MakeData()
futureData1 map { data => {
futureData1 map { data2 => {
assert(data.value == data2.value)
}
}
}
}
}
Чтение https://www.scalatest.org/user_guide/async_testing , похоже, нет документации, описывающей тестирование нескольких фьючерсов.
Комментарии:
1. Первым
map
должно быть aflatMap
, и это, вероятно, выглядело бы лучше при использованииfor
Ответ №1:
Используя map
такой вряд ли будет работать так, как вы хотите — assert внутри карты не беги, пока будущее, что, вероятно, произойдет после того, как испытания уже закончены, а даже если и не исключение из утвердить будут обернуты в будущем и никогда не бросают на главном потоке, поэтому тест всегда проходит.
Похоже, вы используете scalatest, так что, вероятно, имеет смысл вмешаться, Eventually
чтобы вы могли выполнять эти утверждения.:
val f = doStuff()
eventually {
f.value shouldBe Some(Data(2))
}
Или, если вы предпочитаете ScalaFutures
семантику ( ScalaFutures
вместо смешивания Eventually
), вы можете сделать:
val f = doStuff()
whenReady(f) { data => assert(data.value == 2) }
Или просто
assert(doStuff().futureValue.value == 2)
Это также делает ответ на ваш вопрос совершенно очевидным:
assert(future1.futureValue == future2.futureValue)
Если вы все еще ищете способ объединить несколько фьючерсов вместе, вы можете использовать .zip
(для двух фьючерсов) или .sequence
(для любого числа):
whenReady(future1 zip future2) { case (d1, d2) => assert(d1 == d2) }
whenReady(Future.sequence(List(f1, f2, f3, f4)) { case first :: rest =>
assert(rest.forall(_ == first))
Комментарии:
1. Или вы просто используете асинхронные спецификации, предоставляемые ScalaTest , которые ожидают
Future[Assertion]
и используют простойfor
2. Или это … Что я ненавижу в scalatest, так это то, что он предлагает слишком много разных способов сделать одно и то же.