2014-09-22 17 views
5

Tôi đã sau:Akka kiểm tra giám sát xử lý lỗi

class Supervisor(dataProvider: DatabaseClientProvider) extends Actor { 
    val writer = context.actorOf(Props(classOf[Child], dataProvider.get)) 
    def receive: Receive = { 
    case Msg => writer forward msg 
    } 
    override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 100) { 
    case e: ConnectionException => Resume 
    } 
} 

class Child(db: DatabaseClient) extends Actor { 
    def receive: Receive = { 
    case msg:Msg => db.write(text) 
    } 
} 

Tôi muốn kiểm tra đơn vị mã ở trên về cơ bản tôi đang cố gắng để đảm bảo khi ngoại lệ xảy ra, chúng tôi vẫn đang nối lại quá trình xử lý như bạn có thể xem dưới đây. Vấn đề là không có ngoại lệ bị bắt bởi người giám sát. Cách tốt nhất để kiểm tra mã dưới đây là gì?

"resume handling messages when exception occurs" in { 

    // Given 
    val msg1 = Msg("Some msg1") 
    val msg2 = Msg("Some msg2") 

    //Throw an exception when attempting to write msg1 
    val databaseClient = mock[DatabaseClient] 
    when(databaseClient.write(msg1.text).thenThrow(ConnectionException("Error!")) 

    val dataProvider = mock[DatabaseClientProvider] 
    when(dataProvider.get).thenReturn(databaseClient) 

    val supervisor = system.actorOf(Props(new Supervisor(dataProvider))) 

    // When 
    intercept[ConnectionException] { 
     supervisor ! msg1 
    } 

    // When 
    supervisor ! msg2 

    // Then 
    verify(databaseClient.write("Some msg"), times(2)) 
} 

Trả lời

8

Để kiểm tra hành vi của người giám sát khi một đứa trẻ ném một ngoại lệ, bạn phải kiểm tra supervisorStrategy. Sử dụng một TestActorRef, bạn có thể nhận được quyền truy cập vào chức năng một phần của s supervisorStrategy và khẳng định rằng một trao Exception kết quả trong dự kiến ​​Directive

val supervisor = TestActorRef[Supervisor](Props(new Supervisor(dataProvider))) 
val strategy = supervisor.underlyingActor.supervisorStrategy.decider 
strategy(ConnectionException("boom")) should be (Resume) 
+0

Tôi hy vọng AKKA đặt tên cho những phương pháp đó theo cách trực quan hơn! – Mayumi

+0

"người quyết định" là mơ hồ nhưng tôi không thấy họ thay đổi tên (phá vỡ khả năng tương thích ngược) vì lợi ích của một thay đổi dễ đọc nhỏ. Oh well –

0

Tôi đặt cược vấn đề là trong phương pháp này:

def receive: Receive = { 
    case Msg => writer forward Msg 
    } 

"trường hợp Msg" được kích hoạt bởi typeclass Msg, không phải bởi một thể hiện của lớp Msg. Một cái gì đó như thế này nên làm việc:

def receive: Receive = { 
    case msg:Msg => writer forward msg 
    } 
+0

tôi gõ sai đến stackoverflow, đó không phải là câu hỏi của tôi. Tôi hỏi làm thế nào để kiểm tra việc xử lý chiến lược từ trẻ em. – Mayumi