2013-05-28 34 views
9

Tôi khá mới đối với Scala vì vậy hãy nhẹ nhàng.Thử nghiệm đơn vị diễn viên Akka với Scala

Trong ứng dụng tôi hiện đang xây dựng, tôi đang sử dụng diễn viên Akka và tôi muốn viết một số bài kiểm tra đơn vị. Tôi đã xem qua điều này official documentation for writing unit tests for Akka actors

nhưng tôi không thể hiểu chính xác cách hoạt động của nó. Cụ thể,

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) 

Khi tôi thử điều đó, tôi nhận được not found: value Success, điều này không đáng ngạc nhiên.

sau đó tôi tìm thấy 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) 

, mà phải thừa nhận là có thể là cũ, nhưng nó rất dễ dàng để hiểu và gần gũi hơn với những gì tôi thường sử dụng khi tôi muốn sử dụng tương lai, và quan trọng nhất là làm việc. Nó đòi hỏi tôi phải tuyên bố một vài sự liên quan như ActorSystem, thời gian chờ và như vậy, mà dường như không phải là trường hợp với cách chính thức ...

Nếu có thể, tôi muốn sử dụng phương pháp được đề xuất bởi tài liệu chính thức, vì vậy tôi sẽ đánh giá cao nếu ai đó có thể giúp tôi hiểu cách thức hoạt động (đặc biệt là bit Thành công) và cách sử dụng nó.

+1

làm bạn phải nhập khẩu như 'scala.util._' hoặc' scala.util.Success '? – 4lex1v

Trả lời

12

Câu trả lời cho câu hỏi của bạn có thể quá dài, vì không thể biết bạn thực sự biết bao nhiêu Scala. Tôi sẽ cố gắng trả lời càng ngắn càng tốt, nhưng đừng ngần ngại để yêu cầu làm rõ tại bất kỳ thời điểm nào. Tôi cũng xin lỗi thay mặt cho toàn bộ cộng đồng stackoverflow để khiến bạn cảm thấy cần phải xin lỗi vì thiếu kỹ năng trước khi đặt câu hỏi.

Trong Scala 2.10, khái niệm về Try đã được giới thiệu. Nó rất giống với Option. Option là khái niệm xử lý null s. Giá trị loại Option có thể có hai dạng: Some(value) hoặc None. Khi bạn có giá trị Option al, bạn có thể so khớp mẫu trên đó để xem đó có phải là số Some hoặc None và sau đó hành động tương ứng. Kết hợp mẫu xảy ra ở nhiều nơi trong Scala và một trong số đó là trong quá trình khởi tạo val s. Dưới đây là một vài ví dụ:

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 là khái niệm về xử lý ngoại lệ. Giá trị loại Try có thể có hai dạng: Success(result) hoặc Failure(throwable). Khi bạn có giá trị loại Try, bạn có thể đối sánh mẫu trên đó để xem đó có phải là Success hoặc Failure.

Đây là những gì xảy ra trong mã của bạn (khớp mẫu trên Success). Ngược lại với Option hai hình thức Try không nằm trong phạm vi theo mặc định, điều này gây ra lỗi biên dịch. Điều này sẽ khắc phục sự cố:

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

Tương tự tuyệt vời; Tôi hiểu Pattern Matching và Options khá tốt và có thể theo dõi. Tôi chỉ không có ý tưởng về thử, thành công và thất bại. Tôi cho rằng sau đó Future.value.get trả về một giá trị của kiểu Hãy thử sau đó? Nói cách khác, ví dụ theo cách sau: 'val futureValue = future.value.get futureValue trận { trường hợp thành công (x: Int) => x phải được (42) trường hợp _ => sai phải là (true) // chỉ thất bại } ' Các công trình trên cho tôi trong bài kiểm tra của tôi :) – lloydmeta

+1

Vâng, chính xác điều tương tự, nhưng bạn dứt khoát nên đi theo cách tiếp cận được đề xuất bởi Viktor Klang. – agilesteel

+0

Cảm ơn, tôi sẽ chấp nhận câu trả lời của bạn vì nó đã trả lời câu hỏi của tôi và xóa bỏ sự nhầm lẫn của tôi về Thành công nhất. – lloydmeta

4

Thứ nhất, đây không phải là mô hình tốt để sử dụng trên giá trị tương lai, điều này có thể làm tăng ngoại lệ nếu có lỗi. Bạn nên sử dụng Await.Kết quả, như trong ví dụ giây của bạn, hoặc mẫu sử dụng phù hợp để làm việc với Thành công và thất bại:

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

sử dụng SuccessFailure nhập khẩu scala.util._ hoặc scala.util.{Success, Failure}

Here là một tài liệu chính thức cho phiên bản mới nhất 2.2 M3.

5

Có thử nghiệm của bạn kéo dài tuổi TestKit và sau đó thêm "với ImplicitSender" và sau đó bạn có thể làm những việc như:

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

Cảm ơn, điều này thực sự hữu ích. Sau một số tìm kiếm tôi đã tìm thấy [ví dụ này] (http://doc.akka.io/docs/akka/2.1.4/scala/testkit-example.html) minh họa cách sử dụng ImplicitSender với DefaultTimeout, v.v. – lloydmeta

Các vấn đề liên quan