Scala 测试期货/可观测数据的接收观测值
我有: 我可以通过测试来测试输入列表是否确实传递给了可观察对象:Scala 测试期货/可观测数据的接收观测值,scala,rx-java,reactive-programming,scalatest,rx-scala,Scala,Rx Java,Reactive Programming,Scalatest,Rx Scala,我有: 我可以通过测试来测试输入列表是否确实传递给了可观察对象: val observable: Observable[Int] = Observable.from(List(5)) 其中materialevalues为: materializeValues(observable) should contain (5) 现在,如果我从未来创建一个可观察的对象,那么当测试超时时,我似乎不能对测试使用materialevalues。因此,如果我有: def materializeValues[T
val observable: Observable[Int] = Observable.from(List(5))
其中materialevalues
为:
materializeValues(observable) should contain (5)
现在,如果我从未来创建一个可观察的对象,那么当测试超时时,我似乎不能对测试使用materialevalues
。因此,如果我有:
def materializeValues[T](observable: Observable[T]): List[T] = {
observable.toBlocking.toIterable.toList
}
它超时且未通过测试。在具体化这两个观测值的过程中有什么不同,这导致我无法阻止它
另外,什么是测试可观察对象的idomatic方法?有没有办法不调用
toblock
?我认为问题在于您使用了AsyncWordSpecLike
(顺便问一下,为什么AsyncWordSpecLike
而不是AsyncWordSpecLike
)AsyncWordSpecLike
/AsyncWordSpec
旨在简化未来的测试。不幸的是,Observable
是一个更强大的抽象,无法轻松映射到未来的
特别是AsyncWordSpecLike
/AsyncWordSpec
允许您的测试返回Future[Assertion]
。为了使之成为可能,它提供了自定义隐式ExecutionContext
,可以强制执行所有操作,并知道所有计划的作业何时完成。但是,相同的自定义ExecutionContext
是第二个代码不起作用的原因:只有在测试代码的执行完成后,计划作业的处理才会开始,但您的代码会在futVal
上阻塞,因为您很不幸在Future中注册了回调。onComplete
计划在ExecutionContext
。这意味着你有一种自己的线程死锁
我不确定在Scala上测试可观察性的官方方法是什么。在Java中,我认为这是推荐的工具。正如我所说的,observatable
从根本上说比Future
更强大,所以我认为测试observatable
应该避免使用AsyncWordSpecLike
/AsyncWordSpec
。如果切换到使用FlatSpec
或WordSpec
,可以执行以下操作:
val futVal = Future.successful(5)
val observable: Observable[Int] = Observable.from(futVal)
materializeValues(observable) should contain(5)
我无法从未来的中复制可观察的超时的行为。可能您的隐式ExecutionContext
存在一些问题?另外,提供一个始终是一个好主意。这里有一个要点:ExecutionContext
来自AsyncTestSuite
class MyObservableTestSpec extends WordSpec with Matchers {
import scala.concurrent.ExecutionContext.Implicits.global
val testValue = 5
"observables" should {
"be testable if created from futures" in {
val futVal = Future.successful(testValue)
val observable = Observable.from(futVal)
val subscriber = TestSubscriber[Int]()
observable(subscriber)
subscriber.awaitTerminalEvent
// now after awaitTerminalEvent you can use various subscriber.assertXyz methods
subscriber.assertNoErrors
subscriber.assertValues(testValue)
// or you can use Matchers as
subscriber.getOnNextEvents should contain(testValue)
}
}
}