2013-05-28 12 views
9

Ich bin ziemlich neu in Scala, also bitte sei sanft.Akka Schauspieler Einheit testen mit Scala

In der App, die ich gerade baue, benutze ich Akka-Darsteller und ich möchte einige Komponententests schreiben. Ich bin auf diese official documentation for writing unit tests for Akka actors

gestoßen, aber ich konnte nicht genau verstehen, wie es funktionieren sollte. Insbesondere

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) 

Wenn ich versuche, dass ich not found: value Success bekommen, was nicht verwunderlich ist.

Ich fand dann 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) 

, die zwar vielleicht alt, aber es ist leicht zu verstehen und näher zu dem, was ich normalerweise verwenden, wenn ich Futures verwenden möchten, und vor allem funktioniert. Es erfordert, dass ich ein paar implitits wie das ActorSystem, Timeout und dergleichen deklariere, was mit dem offiziellen Weg nicht der Fall zu sein scheint ...

Wenn möglich, würde ich gerne die von die offizielle Dokumentation, also würde ich es begrüßen, wenn mir jemand helfen könnte zu verstehen, wie es funktioniert (insbesondere das Success-Bit) und wie man es benutzt.

+1

haben Sie importieren wie 'scala.util._' oder' scala.util.Success '? – 4lex1v

Antwort

12

Die Antwort auf Ihre Frage könnte zu lang sein, weil es unmöglich ist zu wissen, wie viel Scala Sie tatsächlich wissen. Ich werde versuchen, meine Antwort so kurz wie möglich zu machen, aber zögern Sie nicht zu fragen, um Klärung zu jedem Zeitpunkt. Ich entschuldige mich auch im Namen der gesamten stackoverflow-Community dafür, dass Sie das Gefühl haben, dass Sie sich entschuldigen müssen, weil Sie offensichtlich keine Fähigkeiten haben, bevor Sie eine Frage stellen. In Scala 2.10 wurde ein Konzept Try eingeführt. Es ist sehr ähnlich zu Option. Option ist ein Konzept der Handhabung null s. Ein Wert vom Typ Option kann zwei Formen annehmen: Some(value) oder None. Wenn Sie einen Option al-Wert haben, können Sie ein Muster darauf abgleichen, um zu sehen, ob es ein Some oder ein None ist, und dann entsprechend handeln. Musterübereinstimmung tritt an vielen Stellen in Scala auf und eines davon ist während der Initialisierung von val s. Hier sind einige Beispiele:

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 ist ein Konzept der Behandlung von Ausnahmen. Ein Wert vom Typ Try kann zwei Formen annehmen: Success(result) oder Failure(throwable). Wenn Sie einen Wert vom Typ Try haben, können Sie ein Muster dafür erstellen, um zu sehen, ob es ein Success oder ein Failure ist.

Dies geschieht in Ihrem Code (Mustererkennung auf Success). Im Gegensatz zu Option sind die beiden Formen Try standardmäßig nicht im Umfang, was den Kompilierungsfehler verursacht. Dadurch wird es beheben:

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

Große Analogie; Ich verstehe Pattern Matching und Optionen ziemlich gut und war in der Lage zu folgen. Ich hatte nur keine Ahnung von Versuch, Erfolg und Misserfolg. Ich nehme dann an, dass Future.value.get einen Wert vom Typ Try dann zurückgibt? Mit anderen Worten, das Beispiel in der folgenden Art und Weise: 'val FUTURE = future.value.get FUTURE Spiel { Fall Erfolg (x: Int) => x muss sein (42) Fall _ => false muss sein (wahr) // einfach scheitern } ' Das obige funktioniert für mich in meinen Tests :) – lloydmeta

+1

Ja, genau das gleiche, aber Sie sollten definitiv für den Ansatz von Viktor Klang vorgeschlagen gehen. – agilesteel

+0

Danke, ich akzeptiere deine Antwort, weil sie meine Frage beantwortet und meine Verwirrung über den Erfolg am meisten geklärt hat. – lloydmeta

4

Erstens ist es kein gutes Muster auf Futures Wert erhalten zu verwenden, kann dies eine Ausnahme ausgelöst, wenn ein Fehler ist. Sie sollten entweder warten.Ergebnis, wie in Ihrer Sekunde Beispiel, oder passende Verwendung Muster mit Erfolg und Misserfolg zu arbeiten:

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

Success und Failure Import zu verwenden scala.util._ oder scala.util.{Success, Failure}

Here ist eine offizielle Dokumentation für die neueste Version 2.2- M3.

5

Haben Sie Ihren Test der Testkit und fügen Sie dann „mit ImplicitSender“ erweitern und dann können Sie tun Dinge wie:

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

Danke, das hat wirklich geholfen. Nach einigem Suchen habe ich [dieses Beispiel] (http://doc.akka.io/docs/akka/2.1.4/scala/testkit-example.html) gefunden, das demonstriert, wie ImplicitSender mit DefaultTimeout, etc. benutzt wird. – lloydmeta

Verwandte Themen