2013-09-03 28 views
10

Tôi đang cố gắng để viết một bài kiểm tra đó sẽ xác minh rằng nam diễn viên của tôi dưới đây đang tạo ra một heartBeatExpireWorker và heartBeatAccepter, nhưng tôi không có ý tưởng làm thế nào để làm điều đó. Đầu tiên tôi đã nghĩ tôi có thể sử dụng Mockhito giả hoặc gián điệp thay cho bối cảnh và sau đó xác minh rằng tôi gọi là actorOf, nhưng tôi không thể tìm ra cách để chèn ngữ cảnh mà không phá vỡ khuôn khổ thử nghiệm Akka.Làm thế nào để kiểm tra rằng diễn viên Akka đã được tạo ra trong Scala

Sau đó, tôi đã suy nghĩ rằng tôi có thể gửi một thông điệp tới Xác định người lao động để xác minh rằng chúng tồn tại. Nhưng nó đã xảy ra với tôi rằng điều đó sẽ không làm việc, hoặc bởi vì Akka TestKit dường như không tạo ra các diễn viên trẻ em của một diễn viên được thử nghiệm. Nó chỉ có thể thực hiện trong các thử nghiệm có thể đứng trong các diễn viên lân cận.

class HeartBeatPumpWorker(chatService: ChatService, target: HeartBeatMessageCmd) extends Actor with ActorLogging with 
WorkersReference { 

    val heartBeatInterval = chatService.getHeartBeatInterval 

    val tick = context.system.scheduler.schedule(0 millis, heartBeatInterval millis, self, SendHeartBeat(target)) 

    override def postStop() = tick.cancel() 

    def receive = { 
    case SendHeartBeat(command: HeartBeatMessageCmd) => 
     log.debug("Sending heartbeat") 
     //Send heartbeat to GWT 
     val userTarget = NetworkWorker.buildEventUserTarget(command.getEventCode, command.getUser) 

     val uuid: String = UUID.randomUUID().toString 
     val freshCommand = new HeartBeatMessageCmd(command.getUser, command.getEventCode, uuid, command.getUserSession) 
     networkWorker ! NetworkBroadcast(userTarget, freshCommand) 

     val heartBeatId: String = freshCommand.getUuid 
     //create expirer 
     val heartBeatExpireWorkerRef = context.actorOf(HeartBeatExpireWorker.props(chatService, freshCommand), 
     HeartBeatExpireWorker.name(heartBeatId)) 
     val heartBeatAccepterRef = context 
     .actorOf(HeartBeatAcceptWorker.props(chatService, freshCommand), HeartBeatAcceptWorker.name(heartBeatId)) 

     //record heartbeat 
     chatService.saveSentHeartbeat(heartBeatId, freshCommand.getUserSession, freshCommand.getEventCode, 
      freshCommand.getUser, 
     freshCommand.getTimeCmdGenerated) 
    case _ => 
     log.error("Pumper received unknown message. This shouldn't happen " + sender.path.toString) 
     self ! PoisonPill 
    } 

} 


object HeartBeatPumpWorker { 
    def name(eventCode: String, user: String, sessionId: String) = f"HeartBeatPumpWorker-$eventCode-$user-$sessionId" 

    def path(eventCode: String, user: String, sessionId: String) : String = { 
    EventWorker.Path + "/" + name(eventCode, user, sessionId) 
    } 

    def props(chatService: ChatService, heartBeatMsgCmd: HeartBeatMessageCmd) = { 
    Props(classOf[HeartBeatPumpWorker], chatService, heartBeatMsgCmd) 
    } 
} 

Trả lời

3

Tiêm Props cho trẻ em (ví dụ HeartBeatAcceptWorker.props) trong constructor của phụ huynh HeartBeatPumpWorker. Vượt qua bất kỳ Props nào bạn muốn từ thử nghiệm. Để cha mẹ nhanh chóng cho trẻ em qua số Props được cung cấp. Tương tác với trẻ em. Phần cuối cùng phụ thuộc vào luồng dữ liệu của bạn. Ví dụ, nếu cha mẹ bảo vệ bạn khỏi các trẻ em, nhưng đại biểu tin nhắn cho họ, gửi tin nhắn cho phụ huynh. Nếu trẻ em nói chuyện với nhau sử dụng thăm dò thử nghiệm hoặc một cái gì đó tương tự.

+0

Tôi không chắc chắn tôi làm theo. Tôi cần phải có Props định nghĩa trong nhận thức bởi vì tôi đang sử dụng đối số đến để xác định con đường cho heartBeatExpireWorkerRef mới được tạo của tôi và heartBeatAccepterRef. Vì vậy, tôi không nghĩ rằng tôi có thể có đạo cụ tiêm. – HappyCoder86

+1

Vậy thì bạn cần tiêm chúng qua tin nhắn. Như cuối cùng, bạn có thể tiêm tên cho đứa trẻ thông qua tin nhắn và sau đó nhìn đứa trẻ với 'ActorSelection'. cái đó có giúp ích không? – agilesteel

+0

Đó là âm thanh tốt, nhưng các Akka TestKit phép một diễn viên để làm cho diễn viên nhí? Tất cả các ví dụ tôi đã tìm thấy cho đến nay chỉ cho phép một diễn viên tương tác với các đầu dò thử nghiệm. Tôi đã không tìm thấy bất kỳ thử nghiệm mẫu nào mà một diễn viên được thử nghiệm tạo ra các diễn viên con. Bạn có biết nơi tôi có thể tìm thấy một ví dụ thử nghiệm như thế? – HappyCoder86

13

Kỹ thuật Tôi hiện đang sử dụng là để đánh chặn tạo diễn viên và tạo TestProbes. Trong diễn viên của tôi, tôi trộn trong một đặc điểm riêng biệt ActorMaker:

trait ActorMaker { this: Actor => 
    def makeActor(props: Props) = context.actorOf(props) 
} 

Và sử dụng nó trong MyActor extends Actor with ActorMaker thay vì context.actorOf.

Đối với các bài kiểm tra tôi đã một TestProbeMaker để chụp tất cả các diễn viên tạo và đạo cụ của họ:

trait TestProbeMaker { this: Actor => 
    val probes = ListBuffer.empty[(Props, TestProbe)] 
    def makeActor(props: Props) = { val probe = TestProbe() 
    probes += (props -> probe) 
    probe.ref 
    } 
} 

Và tôi trộn nó trong khi kiểm tra

val actorUnderTest = TestActorRef(Props(new MyActor with TestProbeMaker)) 

Bằng cách đó tôi có thể khẳng định chính xác những gì diễn viên được tạo ra. Tôi cũng có thể sử dụng probe.expectMsg để khẳng định rằng thông điệp được gửi đến những diễn viên tạo ra.

Để truy cập đầu dò sử dụng actorUnderTest.underlyingActor.asInstanceOf[TestProbeMaker]

+0

Xin chào, điều này có vẻ tốt đẹp. Nhưng không rõ cách bạn có thể truy cập vào TestProbe. Trong lớp kiểm tra của bạn như thế nào bạn truy cập vào danh sách 'thăm dò' cho rằng đó là một lĩnh vực hỗn hợp trong khi diễn viên của bạn theo thử nghiệm được tạo ra? Tôi không cho rằng bạn có một ví dụ mã? – C0deAttack

+0

@ C0deAttack bạn có thể vào danh sách các đầu dò bằng cách sử dụng 'actorUnderTest.underlyingActor' bằng cách truyền nó tới TestProbeMaker. – Andrejs

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