2017-03-26 16 views
1

私は俳優ベースのアプリケーション用のテストケースを作成しています。Akka TestKitプローブのStrictモード

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を実行するオプションがあるので、すべてのメッセージが何とか予想される必要がありますか?好ましい方法は、TestKitActorSystem又はTestProbe構成を介して行われるが、各テストケースを修正する必要としない任意の溶液が微細でテストを失敗する何かを

答えて

2

(その結果、各通信の終了にexpectNoMsg()を起動する解決策ではない)、それテストを実行する何らかの種類のスレッドのアサーションエラーをスローする必要がありますが、プローブは非同期であるため、それに入れたエラー検出は別のスレッドで発生するため、メソッドを呼び出す場所が必要ですテストから(ちょうどexpectNoMsg()のように)。

あなたは、テストツールキットにフックするなど、その概念を引き続き抽象化することができます。そうする

可能な方法の1つは、高階関数を使用することになります。

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秒)')、これは間違いなくこの答えに触発されました。 –

関連する問題