带有全局变量的奇怪Scala测试行为:包括延迟使其成功
首先,整个代码都在 我正在使用一个全局对象(我不知道这是否是一个正确的行为)在Spray应用程序中共享状态带有全局变量的奇怪Scala测试行为:包括延迟使其成功,scala,rest,testing,spray,akka-persistence,Scala,Rest,Testing,Spray,Akka Persistence,首先,整个代码都在 我正在使用一个全局对象(我不知道这是否是一个正确的行为)在Spray应用程序中共享状态put添加到映射,get从映射中获取值,因此: path( Segment ) { quien => get { println( Apuestas) // also Thread.wait(100) val esta_apuesta = Apuestas.get( quien ) complete( esta_apuesta ) }
put
添加到映射,get
从映射中获取值,因此:
path( Segment ) { quien =>
get {
println( Apuestas) // also Thread.wait(100)
val esta_apuesta = Apuestas.get( quien )
complete( esta_apuesta )
}
}
(请在查看整个文件)
测试代码的基本部分是
"Crea apuestas correctamente" in {
Put( "/0/2/Alguien") ~> myRoute ~> check {
response.entity should not be equalTo(None)
responseAs[String] must contain("Alguien")
}
Put( "/3/0/Menda") ~> myRoute ~> check {
response.entity should not be equalTo(None)
responseAs[String] must contain("Menda")
}
}
"GET recupera apuesta correctamente" in {
Get("/Alguien") ~> myRoute ~> check {
response.entity should not be equalTo(None)
responseAs[String] must contain("Alguien")
}
}
问题出在第一段代码中。如果我注释掉println
语句,它将不起作用,并且失败。这是错误消息:
[error]“出现内部服务器错误。”不包含“Alguien”(MyServiceSpec.scala:49)
这显然表明“获取”部分还没有工作,或者它在另一个线程中,或者我真的不知道是怎么回事
它可能与同步之类的东西有关,我可能应该以其他方式拥有并声明Apuestas,但我在这方面很新,我很高兴能得到启发
我还将此作为回购协议中的一个问题纳入了hacktoberbest
标签中,以防有人有兴趣推进该领域的一项公关
更新:这似乎与以下问题有关:,也就是说,参与者不应该共享状态,但由程序来执行。问题是,他们确实共享状态,但只有在我们打印的情况下。可能在线程中引入延迟也会有同样的效果吗?我知道这一切都是不好的形式,最糟糕的做法和所有其他的,但如上所述,我很高兴被正确的方法启发
第二次更新:我尝试同步方法,因此:
def add( apuesta: Apuesta ): Apuesta = synchronized {
{
this.apuestas += ( apuesta.quien -> apuesta )
}
apuesta
}
还是没有骰子。我仍然需要打印整个Apuesta对象,或者在线程中等待,这会导致更多问题。println做了什么不能通过同步完成的事情
更新3:测试一段时间后,println只“同步”部分时间。仍然随机失败。它在某种程度上与时间有关,但不知道如何进行。它失败了,因为测试之间存在依赖关系<在发出
Get(“/Alguien”)
请求之前,必须先完成code>Put(“/0/2/Alguien”)。否则,您在info.CC_MII.Apuestas#Apuestas
中没有带有alguien
键的条目,当您尝试访问它时,您的应用程序将失败
您引入了延迟,以打印
的形式或直接使用线程。wait(100)
,这样就给了放置
请求完成的时间。如果您以某种方式延迟GET
的测试执行,而不是将打印或睡眠放入服务中,这会更好一些
另一个选项(更好)可能是将状态注入
info.CC_MII.Apuestas
,即Apuestas
映射的初始值。然后,您可以在测试设置期间提供一些条目,并尝试使用Get
请求取回它们,而不是Alguien
,这似乎不是问题所在。首先,在测试端,调用已完成,否则之前的测试将失败。除了按程序进行调用外,甚至无法对调用进行排序。其次,在服务器端,Thread.wait会导致一些问题:如果测试在测试之后立即完成,它只会丢弃调用。另外,关于我提到的println,有趣的是它需要包含变量,否则它将无法工作。打印带来了一些我不熟悉的变量魔法…Thread.wait在测试中也不起作用。这并不是一种奇怪的行为,它只是并发在我们人类看来的方式。有一些工具和模型旨在缓解跟踪并发应用程序流的困难,但它们只有在您遵守它们的约束时才能工作。没有共享状态等约束。好的开始点:那么,除了重写所有内容之外,还有什么可以做的吗?