Scala java.lang.IllegalStateException:在物化器关闭后尝试物化流
我的应用程序基于Scala Play框架,它有一个在每次加载应用程序时运行的计划作业: //代码段:Scala java.lang.IllegalStateException:在物化器关闭后尝试物化流,scala,testing,playframework,akka,scheduled-tasks,Scala,Testing,Playframework,Akka,Scheduled Tasks,我的应用程序基于Scala Play框架,它有一个在每次加载应用程序时运行的计划作业: //代码段: actorSystem.scheduler.schedule(initialDelay = 0.second, interval = intervalSeconds.second) 在测试期间,如果启用计划作业,则所有测试都会正常完成,并且结果通过(绿色),但我看到日志中随机出现异常: [TaskInvocation]尝试在materializer完成后具体化流 已关闭java.lang.Il
actorSystem.scheduler.schedule(initialDelay = 0.second, interval = intervalSeconds.second)
在测试期间,如果启用计划作业,则所有测试都会正常完成,并且结果通过(绿色),但我看到日志中随机出现异常:
[TaskInvocation]尝试在materializer完成后具体化流
已关闭java.lang.IllegalStateException:正在尝试具体化
已在关闭物化器后的流
akka.stream.impl.PhasedFusingActorMaterializer.materialize(PhasedFusingActorMaterializer.scala:424)
在
akka.stream.impl.PhasedFusingActorMaterializer.materialize(PhasedFusingActorMaterializer.scala:417)
在
akka.stream.impl.PhasedFusingActorMaterializer.materialize(PhasedFusingActorMaterializer.scala:408)
在akka.stream.scaladsl.RunnableGraph.run(Flow.scala:556)处
akka.stream.scaladsl.Source.runWith(Source.scala:103)位于
play.api.libs.streams.strictacculator.run(acculator.scala:203)在
mockws.FakeWSRequestHolder.executeResult(FakeWSRequestHolder.scala:118)
在mockws.FakeWSRequestHolder.execute(FakeWSRequestHolder.scala:103)
在mockws.FakeWSRequestHolder.execute(FakeWSRequestHolder.scala:188)
在mockws.FakeWSRequestHolder.get(FakeWSRequestHolder.scala:181)
我正在使用web服务模拟库:
错误似乎与该库在测试期间如何使用和释放ActorSystem materializer实例有关。对于与actor系统相关的测试配置,我有:
MockWSHelpers中的代码:
trait MockWSHelpers {
private val actorSystem: ActorSystem = actor.ActorSystem("unit-testing")
implicit val materializer: ActorMaterializer = ActorMaterializer()(actorSystem)
val BodyParser: PlayBodyParsers = PlayBodyParsers()
val Action: DefaultActionBuilder = DefaultActionBuilder(BodyParser.anyContent)
def shutdownHelpers(): Unit = {
materializer.shutdown()
Await.result(actorSystem.terminate(), 3.minutes)
}
}
object MockWSHelpers extends MockWSHelpers {
sys addShutdownHook {
shutdownHelpers()
}
}
所有测试将从中继承的基本测试类:
abstract class BaseDomainTest extends PlaySpec with MockitoSugar with MockWSHelpers with BeforeAndAfterAll {
override def afterAll(): Unit = {
shutdownHelpers()
}
}
域测试类将扩展BaseDomainTest,例如:
@RunWith(classOf[JUnitRunner])
class MyTestDomainControllerSpec extends BaseDomainTest {
我的印象是,有时计划的作业在MockWSHelpers的关闭钩子结束之前没有完成,并且抛出异常,当它在关闭钩子结束之前完成时,则没有异常
如何避免上述异常?
备选办法:
一种替代方法是在测试期间完全禁用计划作业,并将其内部业务逻辑移动到一个完全独立的类中。例如:
计划任务:
actorSystem.scheduler.schedule(initialDelay=0.s,intervalSeconds.s){
if(config.isJobEnabled){
myBusinessObject.execute()
}
}
在这种情况下,只需单独测试myBusinessObject.execute()
,而不在测试期间启用计划任务