2013-05-28 68 views
9

我對斯卡拉相當新,所以請溫柔。與斯卡拉Akka演員單元測試

在我正在構建的應用程序中,我使用了Akka actors,並且想編寫一些單元測試。我碰到這official documentation for writing unit tests for Akka actors

但我不明白它應該如何工作。特別是,

val actorRef = TestActorRef(new MyActor) 
// hypothetical message stimulating a '42' answer 
val future = actorRef ? Say42 
val Success(result: Int) = future.value.get 
result must be(42) 

當我嘗試,我得到not found: value Success,這並不奇怪。

我隨後發現this example of how to test Scala actors

val actorRef = TestActorRef[TickTock] 

implicit val timeout = Timeout(5 seconds) 
val future = (actorRef ? new Tick("msg")).mapTo[String] 
val result = Await.result(future, timeout.duration) 

Assert.assertEquals("processed the tick message", result) 

,這固然可能是老了,但很容易理解和更接近時,我想用什麼期貨我通常使用,最重要的工作。它確實需要我聲明像ActorSystem,超時等一些暗示,這似乎並不是官方的情況...

如果可能,我想使用提出的方法官方文檔,所以如果有人能幫助我理解它是如何工作的(特別是成功位)以及如何使用它,我將不勝感激。

+1

你有進口像'scala.util._'或'scala.util.Success '? – 4lex1v

回答

12

您的問題的答案可能太長,因爲不可能知道您實際知道多少Scala。我會盡量使我的答案儘可能短,但不要猶豫,要求澄清在任何時候。我還代表整個stackoverflow社區道歉,因爲在提出問題之前,由於明顯缺乏技能而讓你感到需要道歉。

在斯卡拉2.10引入了一個概念Try。這與Option非常相似。 Option是處理null的概念。類型Option的值可以採用兩種形式:Some(value)None。當你有一個Optional值時,你可以對它進行模式匹配,看它是否是SomeNone,然後相應地採取行動。模式匹配發生在斯卡拉的許多地方,其中之一是在val s的初始化過程中。這裏有幾個例子:

val x = 10 // pattern 'x' on the LHS matches any value on the RHS so 'x' is initialized with 10 
val Some(x) = Some(10) // pattern 'Some(x)' on the LHS matches any value of type 'Some' and binds it's value to x, so 'x' is yet again initialized with 10 

Try是一個處理異常的概念。 Try類型的值可以採用兩種形式:Success(result)Failure(throwable)。當你有一個Try類型的值時,你可以對它進行模式匹配,看看它是Success還是Failure

這就是你的代碼中發生的事情(模式匹配Success)。與Option不同,Try的兩種形式默認情況下不在範圍內,這會導致編譯錯誤。這將解決它:

import scala.util.{Try, Success, Failure} 
+0

偉大的比喻;我很瞭解模式匹配和選項,並且能夠遵循。我只是不知道嘗試,成功和失敗。 我想那麼Future.value.get返回一個Try類型的值呢? 換句話說,以下述方式的例子: 'VAL futureValue = future.value.get futureValue匹配{ 情況下成功(X:強度)=> X必須是(42) 情況_ =>假必須是(true)//只是失敗 }' 上面的作品對我來說在我的測試中:) – lloydmeta

+1

是的,完全一樣的東西,但是你明確地應該選擇Viktor Klang提出的方法。 – agilesteel

+0

謝謝,我會接受你的答案,因爲它回答了我的問題,並最清楚我對成功的困惑。 – lloydmeta

4

首先,它是不是一個很好的模式,使用get期貨價值,這可以引發一個例外,如果有失敗。您應該使用「等待」。結果,就像你秒例如,或使用模式匹配成功和失敗的工作:

future match { 
    case Success(value) => // work with value 
    case Failure(ex) => // work with exception 
} 

使用SuccessFailure進口scala.util._scala.util.{Success, Failure}

Here是最新發布的官方文件2.2- M3。

5

讓你的測試延長TestKit,然後添加「與ImplicitSender」,然後你可以做這樣的事情:

val yourActor = system.actorOf(Props[MyActor]) 
yourActor ! Say42 
expectMsg(42) 
+0

謝謝,這真的很有幫助。經過一番搜索後,我發現[這個例子](http://doc.akka.io/docs/akka/2.1.4/scala/testkit-example.html)演示瞭如何在DefaultTimeout中使用ImplicitSender等。 – lloydmeta