2017-03-26 4 views
1

저는 액터 기반 응용 프로그램을위한 테스트 케이스를 작성하고 있습니다.Akka TestKit 프로브의 엄격한 모드

지금
class MyActor(a: ActorRef, b: ActorRef) extends Actor { 
    override def receive: Receive = { 
     case _ => 
      a ! "Got message!" 
      b ! "Hello!" 
    } 
} 

, 나는 akka-testkitTestProbe을 사용하고 테스트 케이스를 작성하는 다음과 같이 구성 요소 중 하나는 대략 정의 할 수 있습니다.

val a = TestProbe() 
val b = TestProbe() 
val c = system.actorOf(Props(new MyActor(a.testActor, b.testActor))) 

c ! "Message!" 
a.expectMsg("Got message!") 

지금 문제가 테스트 케이스가 b에 보낸 메시지는 예상하지 따라서 검증되지 않은에도 불구하고, 전달하는 것입니다 다음과 같이 테스트 케이스의 중요한 부분이 보인다.

이 특정 문제를 처리 할 테스트 케이스의 시작 부분에 b.expectNoMsg()을 호출 할 수 있다는 것을 알고 있지만 어쨌든 이것이 실제로 확장 가능한 접근 방식이 아니라고 생각합니다. (필자는 이후에 매번 추가해야 할 것입니다. 기대되는 모든 호출은 매우 복잡합니다.)

제 질문은 엄격한 모드에서 akka-testkit을 실행하여 모든 메시지가 어떻게 든 예상 될 수 있도록하는 옵션이 있습니까? 바람직한 방법 TestKit, ActorSystem 또는 TestProbe 구성을 통해이지만, 각 테스트 케이스에 수정이 필요하지만한 솔루션 괜찮 테스트 실패 뭔가

답변

2

(각각의 통신의 종료에 expectNoMsg()를 호출하는 용액 없음) 그것은 어떤 종류의 테스트를 실행하는 스레드의 어설 션 오류를 던져야하지만 프로브가 비동기 적이므로 다른 스레드에서 발생하는 모든 오류 감지가 발생하므로 메서드를 호출해야하는 곳이 필요합니다. 테스트에서 (정확히 expectNoMsg()처럼).

즉, 테스트 툴킷에 연결하는 등의 개념을 추상화 할 수 있습니다.

그 높은 순서 기능을 사용하는 것 한 가지 가능한 방법 :

def failOnUnexpectedMessage[T](test: ActorRef => T): T = { 
    val probe = TestProbe() 
    val result = test(probe.ref) 
    probe.expectNoMsg() 
    result 
} 

당신은 다음 시험에서 그 (여기 Scalatest 단어 사양 스타일)를 사용할 수 있습니다 다음에 대한

"My actor" should { 
    "something something" in failOnUnexpectedMessage { ref => 
    val actor = ...construct and pass it ref as b... 
    ...rest of the test... 
    } 
} 
+0

감사합니다 explaination - 약간 다른 점 (fixture teardown의 모든 프로브에 대해'expectNoMsg (0 seconds)')을했지만, 확실히이 대답에 영감을 받았습니다. –