Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有全局变量的奇怪Scala测试行为:包括延迟使其成功_Scala_Rest_Testing_Spray_Akka Persistence - Fatal编程技术网

带有全局变量的奇怪Scala测试行为:包括延迟使其成功

带有全局变量的奇怪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 ) }

首先,整个代码都在 我正在使用一个全局对象(我不知道这是否是一个正确的行为)在Spray应用程序中共享状态
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在测试中也不起作用。这并不是一种奇怪的行为,它只是并发在我们人类看来的方式。有一些工具和模型旨在缓解跟踪并发应用程序流的困难,但它们只有在您遵守它们的约束时才能工作。没有共享状态等约束。好的开始点:那么,除了重写所有内容之外,还有什么可以做的吗?